SQL Server 索引性能受变量影响

Posted

技术标签:

【中文标题】SQL Server 索引性能受变量影响【英文标题】:SQL Server index performance hindered by variable 【发布时间】:2014-01-29 18:32:59 【问题描述】:

我正在使用 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 是相同的,并且使用了 Index Seek。但是查询 2 进行了索引扫描,并表明我缺少 CreatedOn 上的索引,包括 SomeField。

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

【问题讨论】:

Read This 了解更多信息。 【参考方案1】:

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

您可以与看到此问题的其他人here、here 和here 一起找到更多信息。

【讨论】:

以上是关于SQL Server 索引性能受变量影响的主要内容,如果未能解决你的问题,请参考以下文章

带有时间戳和变量的 SQL Server 查询性能

SQL Server-聚焦事务对本地变量临时表表变量影响以及日志文件存满时如何收缩(三十一)

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响

SQL Server创建复合索引时,复合索引列顺序对查询的性能影响