sql server语言 - ARITHABORT OFF对性能有不利影响



我完全意识到应用程序中的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中复制这一点。

所以我的问题(抱歉到目前为止的背景信息)....The 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

OK。因此,我从Sommarskog文章中提取的引用语句是在数据库级别为80或更高的条件下进行的。

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

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

这解释了:

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

你发布的文章是误导。如果ansi_warnings是ON的,而arithabort是off的,就像人类知道的那样,这对您的查询没有影响。sql server引擎不知道这是否会产生影响,并且会自动强制获取一个新的执行计划,而不使用您的缓存计划。这意味着,如果您有参数嗅探问题,并且有一个糟糕的计划,您将永远不会得到那个糟糕的计划,并在算术中止的情况下使用它。这使得该设置成为查找参数嗅探的一个很好的测试。使用优化未知提示来嗅探参数,而不是更改数据库兼容性级别,这可能会影响其他事情。

最新更新