简体   繁体   English

参数嗅探

[英]parameter sniffing

Suppose we have a poorly performing stored procedure with 6 parameters.假设我们有一个带有 6 个参数的性能不佳的存储过程。 If one of the six parameters is transferred to a local variable within the stored procedure, is that enough to disable parameter sniffing or is it necessary to transfer all 6 parameters that're passed to the stored procedure into local variables within the stored procedure?如果六个参数之一被传输到存储过程中的局部变量,是否足以禁用参数嗅探,或者是否有必要将传递给存储过程的所有 6 个参数传输到存储过程中的局部变量中?

Per Paul White's comment, assigning a variable to a local variable is a workaround from older versions of SQL Server.根据 Paul White 的评论,将变量分配给局部变量是旧版本 SQL Server 的一种解决方法。 It won't help with sp_executesql , and Microsoft could write a smarter parser that would invalidate this workaround.它对sp_executesql没有帮助,Microsoft 可以编写一个更智能的解析器,使此解决方法无效。 The workaround works by confusing the parser about a parameter's value, so in order for it to work for each parameter, you'd have to store each parameter in a local variable.该解决方法的工作原理是将解析器混淆参数值,因此为了使其适用于每个参数,您必须将每个参数存储在局部变量中。

More recent versions of SQL Server have better solutions.更新版本的 SQL Server 有更好的解决方案。 For an expensive query that is not run often, I'd use option (recompile) .对于不经常运行的昂贵查询,我会使用option (recompile) For example:例如:

SELECT *
FROM YourTable
WHERE col1 = @par1 AND col2 = @par2 AND ...
OPTION (RECOMPILE)

This will cause the query planner to recreate ("recompile") a plan every time the stored procedure is called.这将导致查询计划器在每次调用存储过程时重新创建(“重新编译”)计划。 Given the low cost of planning (typically below 25ms) that is sensible behavior for expensive queries.鉴于规划成本低(通常低于 25 毫秒),这是昂贵查询的明智行为。 It's worth 25ms to check if you can create a smarter plan for specific parameters to a 250ms query.值得花 25 毫秒来检查您是否可以为 250 毫秒查询的特定参数创建更智能的计划。

If your query is run so often that the cost of planning is nontrivial, you can use option (optimize for unknown) .如果您的查询运行如此频繁以至于计划成本非常高,您可以使用option (optimize for unknown) That will cause SQL Server to create a plan that it expects to work well for all values of all parameters.这将导致 SQL Server 创建一个计划,它希望对所有参数的所有值都能正常工作。 When you specify this option, SQL Server ignores the first values of the parameters, so this literally prevents sniffing.当您指定此选项时,SQL Server 会忽略参数的第一个值,因此这实际上可以防止嗅探。

SELECT *
FROM YourTable
WHERE col1 = @par1 AND col2 = @par2 AND ...
OPTION (OPTIMIZE FOR UNKNOWN)

This variant works for all parameters.此变体适用于所有参数。 You can use optimize for (@par1 unknown) to prevent sniffing for just one parameter.您可以使用optimize for (@par1 unknown)来防止仅嗅探一个参数。

I got tired off for last two days, and now I find a solution.我前两天累了,现在我找到了解决办法。 If anyone get relief, so I posted my experience here.如果有人得到解脱,所以我在这里发布了我的经验。 I have a query, fairly complex, having 5 CTEs and an union already known for parameter sniffing from its design.我有一个查询,相当复杂,有 5 个 CTE 和一个联合,已知它的设计参数嗅探。 We opted OPTION RECOMPILE to solve it, and it works fairly good.我们选择了 OPTION RECOMPILE 来解决它,而且效果很好。 After 2 years, we create a high available cluster and separate the report server. 2年后,我们创建了一个高可用集群并分离了报表服务器。 All works well for 1 year and now cause of Covid19 we need to shut down for 30 days.一切正常运行 1 年,现在由于 Covid19,我们需要关闭 30 天。 Server is on but all activity goes quite.服务器已开启,但所有活动都进行得很顺利。 Meanwhile we need to truncate the database because of extreme log size and data growth, taking out of available groups and re adding to availability.同时,由于极端的日志大小和数据增长,我们需要截断数据库,删除可用组并重新增加可用性。 From last two date this query shows parameter sniffing activity, and no remedy works except one.从最近两天开始,此查询显示参数嗅探活动,除此之外没有任何补救措施。

The silver bullet saves me is EXEC sp_updatestats .拯救我的银弹是EXEC sp_updatestats

This works for me, and now I have time to find a proper solution for permanent fix.这对我有用,现在我有时间找到合适的永久修复解决方案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM