【发布时间】:2016-05-30 07:07:33
【问题描述】:
当我编写 SQL 时,我会尽量使其具有可读性。除其他外,我经常声明“常量”而不是使用“幻数”。
即而不是
WHERE [Order].OrderType = 3
我愿意
DECLARE @OrderType_Cash AS int = 3;
...
WHERE [Order].OrderType = @OrderType_Cash
这很好用,我没有注意到我通常使用的查询和数据大小有任何性能问题。
最近我阅读了一篇关于参数嗅探和解决方法的文章 (https://blogs.msdn.microsoft.com/turgays/2013/09/10/parameter-sniffing-problem-and-possible-workarounds/)。在文章中提出的解决方法之一是“使用局部变量”。
- 解决方法:使用局部变量 - 此解决方法与前一个非常相似 (OPTION (OPTIMIZE FOR (@VARIABLE UNKNOWN))) - 当 您将参数分配给本地参数 SQL Server 使用统计信息 密度而不是统计直方图 - 所以它估计相同 所有参数的记录数——缺点是一些 查询将使用次优计划,因为密度不精确 足以作为统计直方图。
这让我有点担心,因为我的解释是我可能会因为我使用局部变量而不是“幻数”而在存储过程中得到一个次优计划。
我还觉得 SQL Server 会自动将“幻数”转换为变量以重用计划。
谁能帮我解决这个问题?
- 使用“幻数”和局部变量有区别吗?
- 如果是,它是否仅适用于存储过程,还是也适用于即席查询和动态 SQL?
- 像我这样使用局部变量是不是一个坏习惯?
【问题讨论】:
-
是的,它会导致次优计划。最近的例子dba.stackexchange.com/q/139781/3690
标签: sql-server stored-procedures