使用mssql和节点进行流查询,第一次速度很慢

我正在使用节点js 10.16.0和node-mssql模块连接到数据库。一切正常,我的简单查询也正常。

如果我尝试使用node-mssql example从查询中流式传输数据,则我第一次执行速度非常慢。它不会显示超时错误,但是大约需要一分钟或更长时间才能完成。

根据控制台日志,它带来前55行,然后停下来一会儿。根据下面的代码,当我划分它们时,似乎在数据“组”之间花费了一些时间。如果我第二次或第三次执行相同的查询,则只需一秒钟即可完成。行的总数约为25.000或更多

至少在第一次如何让我的流查询更快?

这是我的代码

在此示例之后,想法是开始流式传输,设置1000行,暂停流式传输,处理该行,使用websocket发送回,清空所有数组,继续进行流式传输,直到完成

let skate= [];
let leather= [];
let waterproof = [];  
let stream_start = new Date();

const request = new sql.Request(pool);
request.stream = true;     
request
.input('id_param',sql.Int,parseInt(id))
.input('start_date_param',sql.VarChar(50),startDate)
.input('stop_date_param',stopDate)  
.query('SELECT skate,leather,waterproof FROM shoes WHERE id = @id_param AND CAST(startTime AS date) BETWEEN @start_date_param AND @stop_date_param ');

request.on('row',row => {     
  rowc++; console.log(rowc);
  rowsToProcess.push(row); 
  if (rowsToProcess.length >= 1000) {  
    request.pause();
    processRows();
  } 
});

const processRows = () => {
  rowsToProcess.forEach((item,index) => { 
    skate.push(item.skate);  
    leather.push(item.leather );  
    waterproof.push(item.waterproof);  
  });              
  measurementsData.push(
    {title: 'Skate shoes',data: skate},{title: 'Leather shoes',data: leather},{title: 'Waterproof shoes',data: waterproof}
  );  
  console.log('another processRows done');  
  //ws.send(JSON.stringify({ message: measurementsData }));
  rowsToProcess = [];
  skate= [];
  leather= [];
  waterproof = [];       
  measurementsData = [];
  request.resume();
}

request.on('done',() => {      
  console.log('rowc,',rowc);
  console.log('stream start,stream_start);
  console.log('stream done,new Date());
  processRows(); 
});
weedssjl 回答:使用mssql和节点进行流查询,第一次速度很慢

我会尝试改善shoes表的索引编制。据我了解,您的查询/索引编制有2个可能的问题:

  • 您按日期时间startTime列进行过滤,但仅id列中有索引(根据评论)
  • 您将日期时间转换为查询的where子句中的日期

索引

由于您仅按日期过滤,没有时间部分,因此建议您创建一个新列startDate,该列是startTime到日期的转换,并在其上创建索引。然后在查询中使用该索引列。

此外,由于仅选择skateleatherwaterproof列,包括它们在索引中的性能可能会更好。了解有关indexes with included columns的信息。

如果您始终选择的数据大于或大于特定日期,则可以查看filtered indexes

避免在以下位置投射

即使一般来说强制转换都不花钱,但在where子句中使用它时,也可能会使SQL Server无法有效利用索引。所以你should avoid it

如果您仅使用日期部分创建了一个新列,并按照上面的引用对其进行了索引,则无需在此处使用强制转换:

WHERE id = @id_param AND startDate BETWEEN @start_date_param AND @stop_date_param
,

如某人先前所建议的那样,当查询第一次运行缓慢但在随后的执行速度很快时,通常是由于缓存。性能很可能与数据库所运行的存储设备有关。

我希望解释计划在两次执行之间不会改变。

,

您应删除对where子句的转换或创建计算索引(如果可能的话,在数据库中)

该列中的操作总是可能会损害您的查询,请尽可能避免

尝试仅设置您的where参数

@start_date_param到日期yyyy-mm-dd 00:00:00

@stop_date_param至今yyyy-mm-dd 23:59:59

AND startTime BETWEEN @start_date_param AND @stop_date_param
本文链接:https://www.f2er.com/3036435.html

大家都在问