SQL Server 似乎主要根据这是否有助于该查询的单次执行更快地返回来决定是否在查询计划中使用并行性。大多数时候,这种评估是相当准确的。有时,优化器可能会做出不太好的选择。但在任何一种情况下,它都没有考虑到该服务器还发生了什么。特别是,如果您运行的服务器每秒处理大量批处理请求,并且这些批处理中的很大一部分正在并行化,您可能会遇到线程不足。也就是说,调度程序都忙于处理并行化的请求或等待它们,没有任何东西可以处理。这可能表现为 SQL Server 无响应。请注意,您可能不一定会看到 100% 的 CPU 利用率。您使用的不是 CPU,而是可用的调度程序。通常,您将等待大量 CX_PACKET 和可能的 THREADPOOL 等待,并且跨调度程序的平均可运行任务计数高于 1。
在某些商店中,工作负载非常复杂,以至于做出了完全消除并行性以完全防止此问题的战略决策。据我所知,这在某些情况下可以很好地工作,尽管我曾与微软工程师交谈过,他们认为这是一个被误导且本质上是坏主意。在这种情况下,您无法通过并行性加速查询,因此执行时间通常与 CPU 利用率成正比。这是一个可以接受的折衷方案,尤其是当您的大多数批处理请求都很小时。
SQL Server 已经将多个查询发送到多个 CPU(如果获得许可)。在较大的查询中,它可以通过启用并行性来打破跨多个线程(可能还有 CPU)的单个查询。
您应该设置并行度以匹配大型查询的一般大小。如果您经常使用 72 连接查询访问数据库,请将其设置为与服务器拥有(或获得许可)一样多的 CPU。如果您经常使用小查询访问服务器,或者您不希望更大的查询占用所有 CPU,则将其设置为更保守的数字(如 1)。
这些是非常通用的指南,来自 MS 的更多信息Parallel Query Processing,以及并行度设置。
我经常看到的场景是一个查询在并行执行时导致自身死锁;这通常是索引错误或更新/删除编写不佳的标志,但有些人会走快速而肮脏的路线并关闭并行性以避免死锁。
以下是我的回答,纯粹基于我的经验和有限的知识:
SQL Server 似乎主要根据这是否有助于该查询的单次执行更快地返回来决定是否在查询计划中使用并行性。大多数时候,这种评估是相当准确的。有时,优化器可能会做出不太好的选择。但在任何一种情况下,它都没有考虑到该服务器还发生了什么。特别是,如果您运行的服务器每秒处理大量批处理请求,并且这些批处理中的很大一部分正在并行化,您可能会遇到线程不足。也就是说,调度程序都忙于处理并行化的请求或等待它们,没有任何东西可以处理。这可能表现为 SQL Server 无响应。请注意,您可能不一定会看到 100% 的 CPU 利用率。您使用的不是 CPU,而是可用的调度程序。通常,您将等待大量 CX_PACKET 和可能的 THREADPOOL 等待,并且跨调度程序的平均可运行任务计数高于 1。
在某些商店中,工作负载非常复杂,以至于做出了完全消除并行性以完全防止此问题的战略决策。据我所知,这在某些情况下可以很好地工作,尽管我曾与微软工程师交谈过,他们认为这是一个被误导且本质上是坏主意。在这种情况下,您无法通过并行性加速查询,因此执行时间通常与 CPU 利用率成正比。这是一个可以接受的折衷方案,尤其是当您的大多数批处理请求都很小时。