SQL Server索引性能受变量的阻碍

时间:2014-01-29 18:32:59

标签: sql-server indexing

我正在使用SQL Server 2008 R2数据库,其中的表包含十亿行的顺序。我想在过去24小时内获得一列的不同值,所以我这样做(查询1):

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > '2014-01-28 12:24:00'

请注意 CreatedOn 上有一个索引,但它不包含 SomeField 。这立即返回。现在,由于这是我经常运行的查询,我决定将其设置为动态,因此我将其更改为(查询2):

DECLARE @StartDate DATETIME = DATEADD(DAY, -1, GETDATE())
SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > @StartDate

我很惊讶这个查询花了很长时间。 (我在一分钟左右后停止了它。)然后我尝试将变量内联这样(查询3):

SELECT DISTINCT SomeField FROM SomeTable WHERE CreatedOn > DATEADD(DAY, -1, GETDATE())

那又快了。查看执行计划,查询1和3是相同的,并使用索引查找。但是查询2执行了索引扫描并建议我在CreatedOn上缺少索引,包括SomeField。

为什么检查变量会突然改变索引的有效性?

1 个答案:

答案 0 :(得分:1)

最可能的原因是,当值被硬编码时,编译器可以使用统计信息来确定要运行的最佳查询。使用变量时,它不会也不必进行扫描。如果您尝试创建存储过程并且以这种方式运行,那么服务器可以使用“parameter sniffing”,您可能会看到更好的性能。

您可以与其他已发现此问题的人hereherehere找到更多信息。