我有两张表Meter
和MeterSpot
。 Meter
表有大约9000条记录,MeterSpot
有大约7000万条记录。 MeterID
列创建两个表之间的关系。这是表格设计的一部分:
Meter
:MeterID int,ContractHour int等......
MeterSpot
:MeterSpotID int,MeterID int,RecordStamp datetime,VolumeToday float等......
我在Meter.MeterID
和MeterSpot.MeterSpotID
上有一个聚集索引,在MeterSpot.RecordStamp
和MeterSpot.MeterID
上有非聚集索引。
现在,我需要查询这两个表中的数据,并获取MeterID
,ContractDate
和VolumeToday
列,其中ContractDate
位于给定日期范围之间。 ContractDate
的计算方法是从ContractHour
Meter
表中减去RecordStamp
MeterSpot
表。
这就是我的尝试:
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
中删除它。性能仍然相同。
问题:
答案 0 :(得分:0)
您可以给出两次日期条件,一次以告知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)