SQL Server 溢出级别 0 - 它是什么?

Moj*_*DBA 13 sql-server execution-plan sql-server-2016

我被要求研究 SQL Server 2016 SP2 中查询的性能,我发现了一些我以前从未见过的东西:

<Warnings>
<SpillToTempDb SpillLevel="0" SpilledThreadCount="1" />
<ExchangeSpillDetails WritesToTempDb="237" />
</Warnings>
Run Code Online (Sandbox Code Playgroud)

有没有人有任何关于“溢出级别 0”的信息?

在每个人都将我发送到 lmgtfy.com 之前 - 我去过那里 :-) 并且在 Google 上实际上只有一个结果;并在该页面上提到了“溢出级别 0”,但没有其他信息。

我查看了我的 SQL Server 内部书籍、Bing.com 等。没有。

我的猜测是它与控制线程溢出或查询内死锁有关?查询本身非常基本;SELECT DISTINCT 有 3 个 INNER JOIN,然后是 2 个 LEFT。

任何线索将不胜感激。

请注意:查询性能已修复,但泄漏的谜团仍然存在。我不是在寻求帮助来改进这个查询——这就是为什么它没有包含在这里。我只是想了解一下溢出 0。

环境:SQL Server 2016 Ent。SP2(无 CU)。MAXDOP = 4 由 RG. 设置,SSMS v18.5

我还在计划中包含了这两个运营商的屏幕截图。

谢谢!

重新分区流

Pau*_*ite 18

一个交换溢出ExchangeSpillDetails)只发生在响应于一个查询内并行死锁。SQL Server 通过强制一个或多个交换(并行运算符)将其缓冲区写入tempdb来解决死锁。

交换溢出没有溢出“级别”的概念(与排序或散列溢出不同,后者可能需要多次传递或递归)。未填充的值报告为零。

您通常希望避免并行死锁,因为它们由资源监视器解决,默认情况下它每五秒唤醒一次。如果最近出现死锁(任何类型),它会更频繁地检查死锁,但它永远不会对性能有好处。

一个更一般的注意事项:并行死锁是由于线程之间的依赖关系而发生的,几乎总是与保留的顺序有关。并行合并连接与两个输入上的保序交换就是一个很好的例子。

有关查询内并行死锁的酷炫可视化,请参阅Forrest McDaniel 的Grokking the Paul White Parallel Deadlock Demo