SQL Server 2014 在 where 子句中使用 DateAdd 来过滤巨大的 table

SQL Server 2014 Using DateAdd in where clause to filter huge table

我有两个 tables MeterMeterSpotMeter table 有大约 9000 条记录,MeterSpot 有大约 7000 万条记录。 MeterID 列创建了两个 table 之间的关系。这是 table 设计的一部分:

我在 Meter.MeterIDMeterSpot.MeterSpotID 上有一个聚集索引,在 MeterSpot.RecordStampMeterSpot.MeterID 上有一个非聚集索引。

现在我需要从这两个 table 查询数据并获取 MeterIDContractDateVolumeToday 列,其中 ContractDate 介于给定的日期范围。 ContractDate 的计算方法是从 MeterSpot table 的 RecordStamp 中减去 Meter table 的 ContractHour

这是我试过的:

SELECT  
    M.MeterID, MS.VolumeToday,  
    DATEADD(hour, -(M.ContractHour), MS.RecordStamp) AS 'ContractDate'      
FROM 
    Meter AS M
INNER JOIN  
    MeterSpot AS MS ON M.MeterID = MS.MeterID   
WHERE 
    (DATEADD(hour, -(M.ContractHour), MS.RecordStamp)  
       BETWEEN @StartDate and @EndDate)

执行此查询需要数小时。我搜索很少,发现当我在 where 子句上添加函数时,不考虑索引。

我在下面尝试过,对于较小的日期范围来说速度相当快。

WHERE MS.RecordStamp BETWEEN @StartDate AND @EndDate)

我试图将 ContractHour 添加到 @StartDate@EndDate 而不是从 RecordStamp 中减去它。性能看起来还是一样。

问题:

  1. 如何过滤计算列中的数据?
  2. 我有更好的方法来完成我的任务吗?
  3. 在处理这种巨大的 table 时,我应该遵循哪些好的做法?

您可以提供两次日期条件,一次是告知 SQL 它可以如何利用其索引来加速您的查询,另一次是精确过滤出您需要的行。 ContractHour 是否有最大值?如果是这样,那么您可以这样做:

select ... 
from Meter m 
join MeterSpot ms on m.MeterID = ms.MeterID
where 
     (ms.RecordStamp between @StartDateMinusMaxContractHour and @EndDate)
     and (dateadd(hour, -@m.ContractHour, ms.RecordStamp) between @StartDate and @EndDate)