3

我完全知道来自应用程序的 SQL 查询通常使用SET ARITHBAORT OFFwhere 作为 SSMS(默认情况下)使用SET ARITHBAORT ON. 我也相信这SET ARITHBAORT OFF只是为了遗留兼容性,真正的查询应该使用SET ARITHBAORT ON.

我有一个作为 C# Console App 批处理文件的一部分运行的查询。SET ARITHBAORT OFF上下文是用和 准备的(默认情况下)SET ANSI_WARNINGS ON。前 92 个调用执行良好,第 93 个调用总是锁定(每个调用使用不同的参数)。SET ARITHBAORT OFF如果我在使用第 93 次调用中的参数调用存储过程之前使用,我已经能够在 SSMS 中重现这一点。

继续我的问题(抱歉到目前为止的背景信息).... Erland Sommarskog 文章指出:

接下来说到ARITHABORT,大家应该知道,在SQL 2005及以后的版本中,只要ANSI_WARNINGS为ON,这个设置影响为零。因此,没有理由为了此事而将其打开。

但是,我使用的是 SQL Server 2014,我发现:

SET ARITHBAORT ON
SET ANSI_WARNINGS ON
EXEC mySP   -- Runs efficiently

运行良好,但

SET ARITHBAORT OFF
SET ANSI_WARNINGS ON
EXEC mySP   -- Runs indefinitely

无限期地运行。因此,如果SET ANSI_WARNINGS ON使ARITHBAORT选项无关紧要,为什么我的查询会锁定?谢谢。

http://www.sommarskog.se/query-plan-mysteries.html

4

2 回答 2

2

好的。所以我从 Sommarskog 文章中引用的语句是在数据库级别为 80 或更高的条件下。

我在MSDN 参考中ARITHABORT找到了这一段:

当数据库兼容级别设置为 90 或更高时,将 ANSI_WARNINGS 设置为 ON 会隐式地将 ARITHABORT 设置为 ON。如果数据库兼容级别设置为 80 或更早,则 ARITHABORT 选项必须显式设置为 ON

这说明:

  1. 为什么ARITHABORT即使ANSI_WARNINGS设置为ON. (数据库级别为 80)
  2. 为什么更改数据库级别似乎可以解决问题(因为我将其更改为 120)
于 2015-07-09T14:22:07.197 回答
0

您发布的文章具有误导性。如果 ansi_warnings 为 ON 并且 arithabort 已关闭,那么您知道这对您的查询没有影响。sql server 引擎不知道这是否会有所不同,并且会自动强制获取新的执行计划而不使用您的缓存计划。这意味着如果您遇到参数嗅探问题并且有一个糟糕的计划,您将永远不会得到那个糟糕的计划并在 arithabort 开启的情况下使用它。这就是使该设置成为查找参数嗅探的绝佳测试的原因。使用优化未知提示进行参数嗅探,而不是更改可能影响其他事情的数据库兼容性级别。

于 2016-01-08T19:15:41.680 回答