我正在一个大约1000万行的大表上进行搜索。我想指定开始日期和结束日期,并返回在这些日期之间创建的表中的所有记录。在DATETIME列上的DATETIME搜索谓词比字符串文字谓词慢得多
这是一个直接的查询:
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= @StartDateTime
AND O.Created < @EndDateTime;
创建是具有非聚集索引中的DATETIME列。
此查询大约需要15秒才能完成。
但是,如果我稍微修改查询,如下所示,则仅需1秒钟返回相同的结果:
declare @StartDateTime datetime = '2016-06-21',
@EndDateTime datetime = '2016-06-22';
select *
FROM Archive.dbo.Order O WITH (NOLOCK)
where O.Created >= '2016-06-21'
AND O.Created < @EndDateTime;
唯一的变化是用一个字符串替换@StartDateTime
搜索谓词。查看执行计划,当我使用@StartDateTime
时,它执行了索引扫描,但是当我使用字符串时,它执行了索引查找,速度提高了15倍。
有谁知道为什么使用字符串文字是如此之快?
我原以为DATETIME列和DATETIME变量之间的比较比将列与日期的字符串表示进行比较要快。我尝试删除并重新创建创建列上的索引,它没有任何区别。我注意到我在生产系统上得到了类似于测试系统上的结果,所以奇怪的行为似乎并不特定于特定的数据库或SQL Server实例。
答案是关系到SQL Server如何识别查询中的变量。如果SQL在运行查询之前无法知道该变量是什么,它可能无法使用缓存计划或无法有效猜测新的计划 –
有一篇关于该主题的好文章,我认为您会发现它有帮助:[SQLmag - 优化变量和参数](http://m.sqlmag.com/t-sql/optimizing-variables-and-parameters) –
@clifton_h:对不起,它需要一段时间,一直忙于工作。您链接的那篇文章回答了我的问题。如果您想将您的评论转换为答案,我会接受它。 –