此查询需要很长时间才能加载,如何才能快速加载结果?

时间:2019-01-07 15:04:32

标签: sql sql-server

此查询需要太多时间来加载;谁能更快?

SELECT 
    c.tank_name, c.tank_id,
    (SELECT TOP 1 b.Level FROM TrackMessages b 
     WHERE b.IMEI = a.IMEI AND b.Timestamp >= @StartDate 
     ORDER BY b.Timestamp ) AS OpeningBalance,
    (SELECT TOP 1 b.Level FROM TrackMessages b 
     WHERE b.IMEI = a.IMEI AND b.Timestamp >= @EndDate 
     ORDER BY b.Timestamp ) AS ClosingBalance,
    (SELECT TOP 1 b.Temp FROM TrackMessages b 
     WHERE b.IMEI = a.IMEI AND b.Timestamp >= @StartDate 
     ORDER BY b.Timestamp) AS StartTemperature,
    (SELECT TOP 1 b.Temp FROM TrackMessages b 
     WHERE b.IMEI = a.IMEI AND b.Timestamp >= @EndDate 
     ORDER BY b.Timestamp ) AS EndTemperature 
FROM 
    device as a
JOIN 
    tbl_static_tank_info as c ON c.tank_id = a.owner_id
WHERE 
    c.client_id = @AppId AND  c.tank_Id IN ({levels})

2 个答案:

答案 0 :(得分:0)

这是您的查询,经过重新格式化并使用有意义的表别名,以便可以更好地理解它:

SELECT sti.tank_name, sti.tank_id,
       (SELECT TOP 1 tm.Level 
        FROM Microframe.dbo.TrackMessages tm 
        WHERE tm.IMEI = d.IMEI AND tm.Timestamp >= @StartDate
        ORDER BY tm.Timestamp
       ) AS OpeningBalance,
       (SELECT TOP 1 tm.Level 
        FROM Microframe.dbo.TrackMessages tm
        WHERE tm.IMEI = d.IMEI AND tm.Timestamp >= @EndDate
        ORDER BY tm.Timestamp
       ) AS ClosingBalance,
       (SELECT top 1 tm.Temp 
        FROM Microframe.dbo.TrackMessages tm 
        WHERE tm.IMEI = d.IMEI AND tm.Timestamp >= @StartDate
        ORDER BY tm.Timestamp
       ) AS StartTemperature,
       (SELECT top 1 tm.Temp 
        FROM Microframe.dbo.TrackMessages tm 
        WHERE tm.IMEI = d.IMEI AND tm.Timestamp >= @EndDate
        ORDER BY tm.Timestamp
       ) AS EndTemperature 
FROM  GatexServerDB.dbo.device d JOIN
      GatexReportsDB.dbo.tbl_static_tank_info sti
      ON sti.tank_id = d.owner_id
WHERE sti.client_id = @AppId AND sti.tank_Id IN ({levels})

通过重组查询,您可以发挥一些技巧。我将从tbl_static_tank_info(client_id, tank_id)device(owner_id, IMEI)TrackMessages(IMEI, Timestamp, Temp, Level)的索引开始。

第一个索引与where子句条件匹配。首先是client_id,因为它是平等的(并且SQL Server不支持称为跳过扫描的东西)。

第二个索引是device的覆盖索引,第一列是join所用的索引。第二列可以包括使用include而不是键。

第三个索引用于相关子查询。这是所有子查询的覆盖索引。可以使用include而不是作为键来包含最后两列。

答案 1 :(得分:0)

我将在您的表中添加以下索引:

create index ix1 on Microframe.dbo.TrackMessages (IMEI, Timestamp, Level);

create index ix2 on Microframe.dbo.TrackMessages (IMEI, Timestamp, Temp);

create index ix3 on GatexReportsDB.dbo.tbl_static_tank_info (tank_id, client_id);