我有一个引用具有 300M 记录的事实表 Cost 的视图。该视图也有几个连接。事实表在 Date 上有一个聚集索引,视图定义是这样的:
select *
from FactCost f
INNER JOIN SomeOtherTable b on a.id = f.id
where f.Date < getdate()-7
如果我像下面这样查询视图,优化器首先处理视图中的谓词,然后处理我查询中的日期。所以它实际上读取了 300M 条记录,只返回 100 万条记录。我无法弄清楚我可以尝试优化哪种解决方法。
SELECT
*
FROM [dbo].vwFactCost
WHERE Date >= '2011-07-01'
AND Date <= '2011-07-31'
编辑
:
我遇到了解决方案不直观的另一种情况。
表:FactRegistration
有 300m 条记录,30 列, RegDate
是日期列
以下是视图定义:
SELECT <columns>
FROM FactRegistration fr
WHERE FR.RegDate < CAST(DATEADD(DAY,-7,GETDATE()) AS DATE)
询问:
SELECT <columns>
INTO #tmp
FROM edw.dbo.vwDemo_slow fr
WHERE fr.RegDate >= CAST('20140501' AS DATE)
AND fr.RegDate <= CAST('20140531' AS DATE)
该计划的结果(https://gist.github.com/gflores1023/f0f0089315841d21ab072837cf12145d):
如果我将视图定义更改为使用此 WHERE 子句:
WHERE FR.RegDate < CAST(CAST(DATEADD(DAY,-7,GETDATE()) AS DATE) AS DATETIME)
我有一个更好的计划(https://gist.github.com/gflores1023/e3904609c98babbbbc646eaec76ebba4):
运行 SQL Server 2016 SP1
我会建议:
getdate()-7
为适当且明确的CONVERT(datetime2(2), DATEADD(DAY, -7, GETDATE()))
SELECT *
,尤其是在视野中所以:
这不仅可以防止隐式转换和 ydm 解释,而且找到下个月的开始比当前的结束更容易。