【发布时间】:2011-01-28 18:47:12
【问题描述】:
查询是包含许多分组级别和聚合操作的单个选择。 使用 SET ARITHABORT ON 只需不到一秒钟,否则需要几分钟。我们已经在 SQL Server 2000 和 2008 上看到了这种行为。
【问题讨论】:
标签: sql-server
查询是包含许多分组级别和聚合操作的单个选择。 使用 SET ARITHABORT ON 只需不到一秒钟,否则需要几分钟。我们已经在 SQL Server 2000 和 2008 上看到了这种行为。
【问题讨论】:
标签: sql-server
有点过时了,但对于遇到类似问题的人来说......
我遇到了同样的问题。对我来说,它原来是参数嗅探,起初我对它的理解不够关心。我添加了一个“设置 arithabort on”,它解决了问题,但后来又回来了。然后我读到:
http://www.sommarskog.se/query-plan-mysteries.html
它清除了一切。因为我使用的是 Linq to SQL 并且解决问题的选项有限,所以我最终使用查询计划指南(请参阅链接末尾)来强制执行我想要的查询计划。
【讨论】:
.NET 应用程序连接时默认禁用该选项,但在 Management Studio 中默认启用。结果是服务器实际上为大多数/所有过程缓存了 2 个单独的执行计划。这会影响服务器执行数值计算的方式,因此您可以根据程序获得截然不同的结果。这实际上只是 proc 获取糟糕执行计划的两种常见方式之一,另一种是参数嗅探。
【讨论】:
SET 选项很容易获得更好的计划并将其误诊为有过错的选项本身。我不相信您链接中的那个人没有这样做。
我认为这几乎可以肯定是参数嗅探。
人们经常说SET OPTIONS 会以这种方式影响性能,但除了您使用索引视图/持久计算列的情况外,我还没有看到此声明的单一权威来源。
在这种情况下(对于 SQL2005+ 和 unless your database is in SQL2000 compatibility mode)。如果您同时拥有ARITHABORT 和ANSI_WARNINGS OFF,那么您会发现索引没有被使用,因此可能需要扫描而不是所需的搜索(以及一些开销,因为无法使用持久的计算结果)。 ADO.NET 似乎默认使用我刚刚进行的快速测试中的ANSI_WARNINGS ON。
in Ben's answer 声称“服务器执行数值计算的方式”可以为结果增加几分钟,否则这将花费不到一秒钟的时间,这对我来说似乎并不可信。我认为往往会发生的是,在调查性能性能问题后,Profiler 被用来识别有问题的查询。这被粘贴到管理工作室并立即运行并返回结果。连接之间唯一明显的区别是ARITH_ABORT 选项。
在管理工作室窗口中的快速测试显示,当打开SET ARITHABORT OFF 并运行查询时,性能问题再次出现,因此显然情况已关闭。实际上,这似乎是Gregg Stark 链接中使用的故障排除方法。
但是,这忽略了这样一个事实,即使用该选项集,您最终可能会从缓存中获得完全相同的错误计划。
即使您以与应用程序连接使用的用户不同的用户身份登录,此计划重用也可能发生。
我首先从 Web 应用程序执行测试查询,然后使用 SET ARITHABORT OFF 从 Management Studio 执行测试查询,然后可以看到使用计数从以下查询中上升。
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 计划,所有计划缓存键必须相同。除了arithabort 本身,其他一些示例是执行用户需要相同的默认架构(如果查询依赖于隐式名称解析)并且连接需要相同的language 集。
【讨论】:
我知道我参加这个聚会迟到了,但对于未来的访客,Martin 是完全正确的。我们遇到了同样的问题——对于 .NET 客户端,SP 运行速度非常慢,而对于 SSMS,它运行得非常快。在探索和解决问题的过程中,我们进行了 Kenny Evitt 在对 Martin 问题的评论中提出的系统测试。
使用 Martin 查询的变体,我在过程缓存中查找 SP,并找到其中两个。查看计划,实际上是一个打开了 ARITHABORT,一个关闭了 ARITHABORT。 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 是正确的——原因是参数嗅探,并且生成的计划并非对所有参数范围都是最佳的。
【讨论】:
Setting ARITHABORT to OFF can negatively impact query optimization leading to performance issues. 是什么意思。他们是否只是在谈论无法在计算列和视图上使用索引(如果 ANSI_WARNINGS 也关闭),或者它确实有其他影响。
刚刚遇到这个问题。正如人们在这里所说,根本原因是多个查询计划,其中一个是次优的。我只是想验证 ARITHABORT 确实可以自己引起问题(因为我遇到问题的查询没有参数,这将参数嗅探排除在等式之外)。
【讨论】:
这让我想起了我在 sql server 2008 天遇到的完全相同的问题。在我们的案例中,我们突然发现一个 sql 作业突然变慢了(通常是几秒钟,现在是 9+ 分钟),该作业需要访问链接服务器,我们在作业的步骤中添加了 set ARITHABORT on,似乎是问题所在解决了几天,然后返回。
我们后来向 MS 支持开了一张票,一开始他们也查不出来,票上报给了一个非常资深的 PFE 团队,两个支持 PFE 试图找出这个问题。
最后一个原因是用户凭据(运行作业步骤)无法访问基础表的统计信息(在链接服务器端),因此执行计划没有优化。
具体来说,用户没有DBCC SHOW_STATISTICS的权限(尽管用户可以从表中选择)。根据MSDN,这个权限规则是在sql 2012 SP1之后改变的
SQL Server 和 SQL 数据库的权限
为了查看统计对象,用户必须拥有该表或 用户必须是 sysadmin 固定服务器角色的成员, db_owner 固定数据库角色,或 db_ddladmin 固定数据库角色。
SQL Server 2012 SP1 修改了权限限制并允许 具有 SELECT 权限的用户可以使用此命令。请注意, SELECT 权限必须满足以下要求 运行命令:
要验证这个问题,我们只需要在链接上运行分析器 服务器端实例并在“错误和警告”部分打开一些事件,如下所示。
希望这次经历可以对社区有所帮助。
【讨论】: