SQL Server 2014性能-参数化SQL与文字
我有一个简单的问题,比如SQL Server 2014性能-参数化SQL与文字,sql,sql-server,Sql,Sql Server,我有一个简单的问题,比如 select count(distinct key) from table where date between '2014-01-01' and '2014-12-31' 它很快(大约1秒),但当我尝试在sp_executesql中对其进行参数化时,速度会慢得多(大约4秒): exec sp_executesql N'select count(distinct key) from table where date between @start and
select count(distinct key)
from table
where date between '2014-01-01' and '2014-12-31'
它很快(大约1秒),但当我尝试在sp_executesql
中对其进行参数化时,速度会慢得多(大约4秒):
exec sp_executesql
N'select count(distinct key) from table where date between @start and @end',
N'@start date, @end date',
@start = '2014-01-01', @end='2014-12-31'
为什么性能会有差异
更新计划差异似乎是因为类型转换。当我将参数类型更改为N'@start datetime,@end datetime',以精确匹配列时,差异消失,参数与常量的计划实际上是相同的(相同的成本等)(Facepalm)
我将接受一个答案,解释为什么类型转换会导致如此巨大的计划差异,而不仅仅是预先转换参数并照常进行
结束更新
这些计划非常相似——相同的索引、相同的估计基数、相同的行计数和相同的I/O——尽管参数化版本中的CPU成本估计更高
具体差异:
- 在两个计划中都会出现相同的索引搜索,但在具有文字的(快速)版本中是并行的,而在具有参数的(慢速)版本中不是并行的。非并行处理器具有较高的CPU估计李>
- 带有参数的版本有一个嵌套的循环联接,它将索引扫描与参数周围的一些逻辑连接起来。这似乎增加了自己的一些CPU开销(嵌套循环中的CPU估计值=7.6)
- 两个版本都将“并行性”作为哈希匹配的子级;在参数化版本中,它是分布式流(CPU估计值=16.5),但在文本版本中,它是重新分区流(CPU估计值=8.3)
- 常量是常量,当查询包含常量时,SQL Server可以完全信任该常量的值,甚至 如果表可以从中推断,则使用这些快捷方式根本不访问表 不返回任何行的约束
- 对于参数,SQL Server不知道运行时值,但在编译查询时会“嗅探”输入值
- 对于局部变量,SQL Server完全不知道运行时值,并应用标准假设。(假设是什么 取决于运算符,以及可以从 唯一索引。)
RECOMPILE
的行为就像查询具有文本值而不是参数一样
针对优化
指示查询优化器对本地查询使用特定值
编译和优化查询时的变量。使用该值
仅在查询优化期间,而不是在查询执行期间
你能粘贴执行计划xml吗?复制帖子?稍有不同的问题。我修复了最初的估算问题和tempdb溢出,但是在文本和参数化SQLI之间仍然存在性能差异。我明白了,我很抱歉。问题是什么?这是一个典型的参数化问题。你研究过这个吗?为什么您不能使用常用的解决方案?谢谢,这是一个有用的资源。我已经发现了局部变量和参数之间的差异,这导致了基数估计的问题。使用使用不同参数编译的查询也可能是一个问题。在我的例子中,这两个问题都不是。我认为“如何使参数化版本的性能与文本版本类似?”的答案是:使用
选项(重新编译)
。当您对参数使用此选项时,您是否获得与文字相同的计划和性能?