并行性能否导致 100% CPU 使用率?

Can parallelism cause 100% CPU usage?

我意识到这个问题有点含糊,但我希望有人能指出我要研究的方向。

我的问题是我在一个程序中有一个查询将我的 SQL 服务器上的 CPU 驱动到 100%。我认为问题与并行性有关,但我不知道如何证实我的怀疑,或者解决问题的最佳方法。

有问题的查询花费了大约 20 分钟 运行使服务器处于 100% CPU,此时我终止了查询。我使用 sys.dm_exec_query_stats 查看查询执行计划。没有索引扫描。索引操作都是查找。我相信我的索引是为这个查询精心挑选的。我确实看到查询中发生了很多并行性。

为了比较,我在 Management Studio 中尝试 运行 在查询 window 中使用相同的查询。查询 运行s 不超过几秒钟,Display Estimated Execution Plan 按钮给了我一个不同的执行计划。此执行计划的不同之处之一是没有并行性。

Here is a link to the query execution plan for the bad query. 看起来像问题的一件事是聚集索引在 PS_TRANSACTION_INV 上查找,谓词在 PS_TRANSACTION_INV.BUSINESS_UNIT 上(在执行计划中一直到右边)显示 1 个估计行。除了几百行之外的所有行都具有值 TRUS1,其余行具有值 TRCN1。 table 有大约 1500 万行并使用大约 22 GB(因此行非常大)。我为 table 的聚簇索引做了 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 CPUs 和 24 GB 内存。查询本身 returns 大约 27,000 行,因此它应该在服务器能够快速执行的能力范围内。这个程序已经 运行ning 好几年了,没有任何问题,所以我认为执行计划一定发生了一些变化。我服务器的 DOP 是 64.

我是否认为问题可能与并行性有关?如果是这样,那怎么会导致应该在一两秒内 运行 的查询使用 100% 的 CPU 超过 20 分钟,但仍未完成?

编辑:在错误查询的执行计划中,我发现其中一个步骤是在理想情况下应该进行聚簇索引查找的字段上进行索引查找。索引查找在table 上,大约有20,000,000 行,但索引字段具有很高的选择性。该索引搜索提供给查询计划中的嵌套循环(具有并行性)。我仍然认为问题在某种程度上与并行性有关。

作为参考,我可以使用非聚集索引 运行 在那个 table 上 SELECT,查询需要几秒钟。

我的第一个问题是您看到了哪些等待类型?

其次,你的服务器是如何设置的(也许 运行 sp_Blitz 并给我们输出 sp_Blitz @OutputType = ‘markdown’, @CheckServerInfo = 1)?

第三,还有什么运行ning,造成了瓶颈?也许从 sp_BlitzFirst or sp_whoisactive 开始,看看发生了什么。

Can parallelism cause 100% CPU usage?

当然可以。 Brent wrote a query to do just this thing。或者,至少,他使用 MAXDOP 0 来确保它发生得更快?

For comparison, I tried running the same query in the query window in Management Studio. The query runs in no more than a few seconds, and the Display Estimated Execution Plan button gives me a different execution plan

我不为布伦特工作,but he talks about this too.. You need to use the actual execution plan, not the estimated. Adding it here,在您的 post 中加入 link 会很有帮助。此外,您还需要确定应用程序是否正在使用缓存的过程计划,或者它们是否都在使用新计划。您可以使用 option(recompile) 强制制定新计划并将苹果与苹果进行比较(但是对于史密斯奶奶来说,红色美味比苹果与橙子更好)

The query itself returns about 27,000 rows, so it should be well within the capability of the server to execute this quickly.

final 如此小的行数不应该用来衡量其性能不佳的原因。在评估最终谓词之前,在 N 个连接数中的某处可能有数百万行被拉回。这是实际执行计划会向您显示瓶颈的地方。

My server's DOP is 64

看起来很高,但您并没有告诉我们您有多少核心 运行ning。幸运的是,Microsoft has good guidance on this.. Before you go changing it at the server level, add a query hint to the bottom of your query... option(maxdop 8). Also, I'd expect to see CXPACKET waits if it was parallelism. Here's a video on that.

最后,请记住 query optimization is hard,即使是服务器。当然,这对您来说不是这种情况,因为您的应用程序会永远占用,并且 SSMS returns 数据很快,这是我希望看到 ASYNC_NETWORK_IO 等待或其他东西的地方。