两个脚本 - 何时以及如何将函数应用于WHERE子句

时间:2013-08-30 16:56:13

标签: sql sql-server query-tuning

WH.dbo.vw_FactTable是一个巨大的表格,在DateKey

上有100万行,索引很好

这几乎是瞬间完成的:

1.

SELECT  COUNT(*)
FROM    WH.dbo.vw_FactTable bi
WHERE   DateKey >= 20130101 AND
        DateKey <= 20130110 

这需要两分钟:

2.

SELECT  COUNT(*)
FROM    WH.dbo.vw_FactTable bi
WHERE   CONVERT(DATETIME,CONVERT(CHAR(8),DateKey,112)) >= '01 JAN 2013' AND
        CONVERT(DATETIME,CONVERT(CHAR(8),DateKey,112)) <= '10 JAN 2013' 

为何如此不同?

执行计划完全不同 - 1似乎选择Merge Join

enter image description here

2用于哈希匹配:

enter image description here

是否有一种明显的方法可以调整查询2

2 个答案:

答案 0 :(得分:2)

在第二个查询中,当您在where子句(Convert)中使用该函数时,将在运行时评估此函数的结果,并且SQL Server查询引擎必须扫描整个表以获取必要的数据。

答案 1 :(得分:1)

人们已经在评论中对其进行了调整,重新编制了指数,这将与您的第一个查询类似:

SELECT  COUNT(*)
FROM    WH.dbo.vw_FactTable bi
WHERE   DateKey BETWEEN CAST(CAST(REPLACE(CAST('01 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)
                    AND CAST(CAST(REPLACE(CAST('10 JAN 2013' AS DATE),'-','')AS VARCHAR(12))AS INT)