我意识到这个问题有点含糊,但是我希望有人可以指出我要研究的方向。
我的问题是,我的程序中有一个查询,该查询将SQL Server上的CPU驱动到100%。我认为该问题与并行性有关,但是我不知道如何证实自己的怀疑或解决该问题的最佳方法。
该查询花费了大约20分钟的时间在100%CPU上运行服务器,这时我杀死了该查询。我使用sys.dm_exec_query_stats
查看查询执行计划。没有索引扫描。索引操作都是寻求。我相信我的索引会很好地用于此查询。我确实看到查询中发生了很多并行性。
为了进行比较,我尝试在Management Studio的查询窗口中运行相同的查询。查询运行的时间不超过几秒钟,“显示估计的执行计划”按钮为我提供了不同的执行计划。此执行计划的差异之一是没有并行性。
Here is a link to the query execution plan for the bad query.似乎有问题的一件事是,PS_TRANSACTION_INV
上的聚集索引查找与PS_TRANSACTION_INV.BUSINESS_UNIT
上的谓词(始终在执行计划的右边)显示1估计行。除几百行外,所有行的值均为TRUS1
,其余几行的值均为TRCN1
。该表具有约1500万行,并使用约22 GB(因此行非常大)。我对表的聚集索引做了DBCC SHOW_STATISTICS
,并且统计信息看起来正确(如下所示)。执行计划的行大小也估计为54 B,这是错误的。真正的行大小更大。
但是,即使执行计划不好,我也不知道该查询如何在不完成的情况下运行24小时以上。
看着sys.sysprocesses
,我可以看到最后一个等待类型是SOS_SCHEDULER_YIELD
。
Here is a link to the query execution plan for the good query.
我的服务器有8个CPU和24 GB的内存。该查询本身返回大约27,000行,因此它应在服务器的能力范围之内,以快速地执行此操作。该程序已经运行了好几年没有问题,所以我认为执行计划必须有所改变。我的服务器的DOP是64。
我是否认为问题很可能与并行性有关?如果是这样,那怎么会导致应该在一两秒钟内运行的查询在20分钟内占用100%的CPU,但仍无法完成?
编辑:在针对该错误查询的执行计划中,我发现其中一个步骤是对理想情况下应该执行聚簇索引查找的字段执行索引查找。索引查找位于具有约20,000,000行的表上,但是索引字段具有很高的选择性。该索引查找将输入到查询计划中的嵌套循环(具有并行性)中。我仍然认为问题在某种程度上与并行性有关。
作为参考,我可以使用非聚集索引在该表上运行SELECT
,查询需要几秒钟。
答案 0 :(得分:3)
我的第一个问题是您看到了什么等待类型?
第二,您的服务器如何设置(也许运行sp_Blitz并向我们提供输出sp_Blitz @OutputType = ‘markdown’, @CheckServerInfo = 1
)?
第三,还有其他事情在运行,导致瓶颈吗?也许从sp_BlitzFirst或sp_whoisactive开始,看看发生了什么。
并行性会导致100%的CPU使用率吗?
可以。 Brent wrote a query to do just this thing。或者,至少,他使用MAXDOP 0
来确保它更快地发生?
为了进行比较,我尝试在以下查询窗口中运行相同的查询 管理工作室。查询运行不超过几秒钟,并且 显示估计执行计划按钮给了我不同 执行计划
but he talks about this too.我不为布伦特工作。您需要使用实际的执行计划,而不是估计的计划。 Adding it here,并在您的帖子中包含链接会很有帮助。另外,您需要确定应用程序是否正在使用缓存的过程计划,或者它们是否都在使用新计划。您可以使用option(recompile)
强制执行一项新计划,并将苹果与苹果进行比较(但像红色美味对史密斯奶奶而言,比对苹果和橙子要好)
查询本身返回大约27,000行,因此应该很好 在服务器的能力范围内以快速执行此操作。
最终的行数如此之小,不应该用来衡量它为什么表现不佳。在N个连接的某个位置,在评估最终谓词之前,可能有数百万行被拉回。这是实际执行计划将向您显示瓶颈的地方。
我的服务器的DOP是64
似乎很高,但是您没有告诉我们有关正在运行多少个内核的所有信息。幸运的是,Microsoft has good guidance on this.。在服务器级别进行更改之前,请在查询底部添加一个查询提示... option(maxdop 8)
。另外,我希望看到CXPACKET
等待并行。 Here's a video on that.。
最后,请记住query optimization is hard,即使对于服务器也是如此。既然您的应用程序永远都在使用,那么这不是您的情况,SSMS可以快速返回数据,这是我希望看到ASYNC_NETWORK_IO
等待的地方。