Mic*_*ray 41 sql-server ssms sql-server-2008 query-performance arithabort
我正在尝试在我维护的Web应用程序中调试SQL超时的来源.我有C#代码的源代码,所以我确切地知道正在运行什么代码.我已经将应用程序调试到执行超时的SQL代码的行,并且我在SQL分析器中观察运行的查询.
当此查询从Web执行时,它会在30秒后超时.但是,当我完全按照Profiler中显示的方式剪切/粘贴查询时,我将其放入SSMS并运行它,它几乎立即返回.我已经跟踪了ARITHABORT在Web正在使用的连接中设置为OFF的问题(也就是说,如果我在SSMS会话中关闭ARITHABORT,它会运行很长时间,如果我将其重新打开,那么它会运行很快).但是,阅读ARITHABORT的描述,它似乎并不适用......我只做一个简单的SELECT,并且根本没有执行任何算法......只有一个带有WHERE条件的INNER JOIN:
为什么ARITHABORT OFF会在此上下文中导致此行为?有什么办法可以改变SSMS对该连接的ARITHABORT设置吗?我正在使用SQL Server 2008.
Aar*_*and 39
那么您的C#代码是使用什么方法向SQL Server发送临时SQL查询?您考虑过使用存储过程吗?这可能会确保相同的性能(至少在引擎中),无论谁调用它.
为什么?ARITHABORT设置是优化程序在确定如何执行查询(更具体地说,用于计划匹配)时查看的内容之一.缓存中的计划可能与SSMS具有相同的设置,因此它使用缓存的计划,但是使用相反的设置,您的C#代码正在强制重新编译(或者您可能正在缓存中遇到真正的BAD计划),在很多情况下肯定会损害性能.
如果您已经在调用存储过程(虽然我认为您没有发布查询,但您可以尝试将OPTION(RECOMPILE)添加到存储过程中的违规查询(或查询)中.这将意味着这些语句将始终重新编译,但它可能会阻止使用您似乎遇到的错误计划.另一个选项是确保在编译存储过程时,使用SET ARITHABORT ON执行批处理.
最后,您似乎在询问如何更改SSMS中的ARITHABORT设置.我想您要问的是如何在代码中强制使用ARITHABORT设置.如果您决定继续从C#应用程序发送临时SQL,那么您当然可以发送一个命令作为具有由分号分隔的多个语句的文本,例如:
SET ARITHABORT ON; SELECT ...
Run Code Online (Sandbox Code Playgroud)
有关此问题发生原因的更多信息,请参阅Erland Sommarskog的精彩文章:
Str*_*ior 12
这个答案包括解决此问题的方法:
通过在数据库上以管理员身份运行以下命令,无论ARITHABORT设置如何,所有查询都按预期运行.
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Run Code Online (Sandbox Code Playgroud)
似乎大多数人最终很少发生这个问题,而上述技术是一个体面的一次性修复.但是,如果一个特定的查询显示出这一问题不止一次,更长远的解决这个问题是使用查询提示像OPTIMIZE FOR
和OPTION(Recompile)
,如在 这篇文章.
我以前多次遇到过这个问题,但是如果您有一个存在相同问题的存储过程,则删除并重新创建存储过程将解决该问题。
这称为参数嗅探。您需要始终本地化存储过程中的参数,以避免将来出现此问题。
我知道这可能不是原始发帖者想要的,但可能会帮助遇到同样问题的人。