ARITHABORT OFF 对性能产生不利影响

ARITHABORT OFF adversely affecting performance

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

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

关于我的问题(抱歉到目前为止的背景信息).... Erland Sommarskog article 状态:

Next, when it comes to ARITHABORT, you should know that in SQL 2005 and later versions, this setting has zero impact as long as ANSI_WARNINGS is ON. Thus, there is no reason to turn it on for the sake of the matter.

但是,我使用的是 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

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

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

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

我在 MSDN reference for ARITHABORT 中找到了这段话:

Setting ANSI_WARNINGS to ON implicitly sets ARITHABORT to ON when the database compatibility level is set to 90 or higher. If the database compatibility level is set to 80 or earlier, the ARITHABORT option must be explicitly set to ON.

这说明:

  1. 即使 ANSI_WARNINGS 设置为 ON,为什么我在更改 ARITHABORT 时会出现差异。 (数据库级别为 80)
  2. 为什么更改数据库级别似乎可以解决问题(因为我将其更改为 120)

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