该查询是一个包含大量分组级别和合并操作的单选。
将SET ARITHABORT ON花费不到一秒钟,否则花费了几分钟。我们已经在SQL Server 2000和2008上看到了此行为。

#1 楼

有点过时了,但是对于任何在这里遇到类似问题的人...

我也遇到了同样的问题。对我来说,原来是参数嗅探,起初我对它并不了解。我添加了一个'set arithabort on'来解决问题,但是后来又回来了。然后我读到:

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

它清除了所有内容。因为我使用的是Linq to SQL,并且解决该问题的选项有限,所以我最终使用了一个查询计划指南(请参阅链接结尾)来强制执行我想要的查询计划。

评论


六年多以后,此答案中给出的链接仍然是“必读”……并且仍然是最新的,最新修订版为17年12月。

– takrl
18年1月3日在8:12

#2 楼

.NET应用程序与默认情况下禁用的选项连接,但默认情况下在Management Studio中启用了该选项。结果是服务器实际上为大多数/所有过程缓存了2个单独的执行计划。这会影响服务器执行数值计算的方式,因此,根据过程,您可能会获得截然不同的结果。实际上,这只是proc可以获取可怕的执行计划的2种常见方式之一,另一种是参数嗅探。

看看https://web.archive.org/web/20150315031719 /http://sqladvice.com/blogs/gstark/archive/2008/02/12/Arithabort-Option-Effects-Stored-Procedure-Performance.aspx进行了更多讨论。

评论


我同意这个答案的一半。不过,我对数值计算的要求非常怀疑!

–马丁·史密斯
2010年7月18日在9:31

@马丁:我想我不清楚。我只是说ARITHABORT ON使SQL Server在任何div / 0或算术溢出错误上都会出错。当它关闭时,它会继续前进,并且由于任何原因都可能导致各种可怕的问题。

–RandomBen
2010年7月19日在13:27

@Ben-是的,对不起,我不想特别抨击您的答案,我只是指出,更改SET选项以获得更好的计划并将其误诊为Option本身很容易出错。我不确信您链接中的那个人没有这样做。

–马丁·史密斯
2010年7月19日在13:37

@Martin-没问题,我不认为你在攻击我。我链接的其他讨论可能还不清楚。我只是想提供佐证。

–RandomBen
2010年7月19日在14:08

回想一下,@马丁我相信你是正确的。

–乔纳森·艾伦
11年7月27日在17:06

#3 楼

我认为这几乎可以肯定是参数嗅探。

经常有人说SET OPTIONS会以这种方式影响性能,但是除了您使用索引视图/持久化计算列的情况外,我还没有看到这一说法的权威来源。 />
在这种情况下(对于SQL2005 +,除非您的数据库处于SQL2000兼容模式下)。如果同时拥有ARITHABORTANSI_WARNINGS,那么您会发现索引没有被使用,因此可能是扫描而不是所需的查找(以及一些开销,因为无法使用持久的计算结果)。 ADO.NET似乎默认是从我刚刚做的快速测试中得到OFF

Ben的回答声称“服务器执行数值计算的方式”可能会增加几分钟的结果,否则将花费几分钟不到一秒钟对我来说似乎并不可信。我认为趋于发生的是,在调查性能性能问题时,探查器用于识别有问题的查询。将其粘贴到Management Studio中并运行并立即返回结果。连接之间唯一明显的区别是ANSI_WARNINGS ON选项。

在Management Studio窗口中进行的快速测试表明,打开ARITH_ABORT并运行查询后,性能问题再次出现,因此显然已关闭了案例。确实,这似乎是Gregg Stark链接中使用的故障排除方法。

但是忽略了以下事实:使用该选项集,最终可能会从缓存中获得完全相同的错误计划。

即使您以与应用程序连接使用的用户名不同的用户身份登录,该计划重用仍可能发生。

我通过首先从Web应用程序执行测试查询来对此进行测试然后从管理工作室使用SET ARITHABORT OFF,可以从下面的查询中看到使用量增加。

SELECT usecounts, cacheobjtype, objtype, text ,query_plan
FROM sys.dm_exec_cached_plans 
CROSS APPLY sys.dm_exec_sql_text(plan_handle) 
CROSS APPLY sys.dm_exec_query_plan(plan_handle) 


为了使此共享pf计划实际发生,所有计划缓存键必须相同。与SET ARITHABORT OFF本身一样,其他一些示例是执行用户需要相同的默认架构(如果查询依赖于隐式名称解析),而连接也需要相同的arithabort集。

计划缓存的完整列表钥匙在这里

#4 楼

我知道我参加这个聚会很晚,但是对于将来的来访者,马丁是完全正确的。我们遇到了同样的问题-对于.NET客户端,SP运行非常缓慢,而对于SSMS却很快。在探究和解决问题时,我们进行了肯尼·埃维特(Kenny Evitt)在评论马丁的问题时所要求的系统测试。他们两个人。从计划来看,实际上是一个人开了阿里巴特,另一个人开了阿里巴特。 ARITHABORT OFF版本具有索引查找,而ARITHABORT ON版本使用相同输出的索引扫描。给定涉及的参数,索引查找将需要对数千万条记录进行查找以进行输出。

我从缓存中清除了两个过程,并让.NET客户端再次运行SP,使用相同的参数(对于活动频繁的客户而言,日期范围宽泛)。 SP立即返回。缓存的计划使用了以前在ARITHABORT ON计划中使用的相同索引扫描-但这一次该计划用于ARITHABORT OFF。我们在SSMS中使用相同的参数运行了SP,然后再次立即获得了结果。现在,我们看到使用索引扫描为ARITHABORT ON缓存了第二个计划。

然后我们清除了缓存,在SSMS中以较小的日期范围运行SP,并获得了即时结果。我们发现,生成的缓存计划具有索引查找,因为先前通过扫描处理了相同的输出(这也是原始计划中具有ARITHABORT OFF的查找)。再次从SSMS,我们以相同的宽日期范围运行了SP,并且看到了与原始.NET请求中相同的性能。

简而言之,这种差异与ARITHABORT的实际值无关—在任何一个客户端上打开或关闭它,我们都能获得可接受或可怕的性能:唯一重要的是编译和缓存计划时使用的参数值。

虽然MSDN指出ARITHABORT OFF本身可能会对查询优化产生负面影响,但我们的测试证实Martin是正确的-原因是参数嗅探,并且生成的计划并非对所有参数范围都最佳。

评论


不知道将ARITHABORT设置为OFF会对短语优化产生负面影响,从而导致性能问题。手段。他们只是在谈论无法在计算的列和视图上使用索引(如果ANSI_WARNINGS也处于关闭状态)还是确实有其他作用。

–马丁·史密斯
13年7月9日在7:22

我不确定。我想知道是否仅仅是MSDN上的某个人遇到了类似的情况,将ARTIHABORT设置为ON,看到了性能改进,并得出了其他人得出的相同结论的情况。至于索引视图和计算列,我不清楚。一方面,它指出如果INSERT,UPDATE或DELETE操作修改存储在其中的数据值,则SET选项必须具有特定的值。在其他地方,他们声明优化器将忽略引用该索引视图或计算列的“任何查询”的索引。两者都是正确的,还是真的“任何查询修改数据”?

–mdoyle
13年7月9日在19:41



#5 楼

刚遇到这个问题。正如人们在这里所说的,根本原因是多个查询计划,其中之一是次优的。我只是想验证ARITHABORT确实可以单独导致问题(因为查询中我遇到了没有参数的问题,这使参数嗅探不受影响)。

#6 楼

这使我想起了我在sql server 2008天内遇到的完全相同的问题。在我们的例子中,我们突然发现一个sql作业突然变慢了(通常是几秒钟,现在是9分钟以上),该作业需要访问链接服务器,我们在作业步骤中添加了ARITHABORT设置,这似乎是问题所在解决了几天,然后返回。

我们后来在MS支持下打开了一张票,最初他们都找不到,将票升级为一支非常高级的PFE团队,并获得了两次支持PFE试图解决此问题。

最终原因是用户凭据(运行作业步骤)无法访问基础表的统计信息(在链接服务器端),因此,执行计划未优化。

详细来说,用户没有DBCC SHOW_STATISTICS的权限(尽管用户可以从表中进行SELECT)。根据MSDN,此权限规则在sql 2012 SP1之后进行了更改。


SQL Server和SQL数据库的权限

为了查看统计对象,用户必须拥有该表,或者
用户必须是sysadmin固定服务器角色,db_owner固定数据库角色或db_ddladmin固定数据库角色的成员。

SQL Server 2012 SP1修改了权限限制,并允许具有SELECT权限的用户使用此命令。请注意,存在
以下要求,SELECT权限足以运行该命令:

要验证此问题,我们只需要在链接的
上运行探查器
/>服务器端实例,并在“错误和警告”部分中打开一些事件,如下所示。




希望这种体验可以以某种方式对社区有所帮助。