SQL Server 2019 自适应连接性能不佳

Fer*_*ere 9 sql-server adaptive-joins query-performance

我将SQL Server从2016年升级到2019年,我的查询的查询计划改变了,它使用了自适应连接,但不幸的是查询的持续时间从1秒增加到1分钟,我改变了连接顺序,问题解决了

T-SQL 代码:

SELECT TOP 100 * FROM dbo.APP App
JOIN dbo.PRS p ON App.PartyId=p.PRSId
LEFT JOIN dbo.Country ON p.NationalityId = dbo.Country.CountryId 
LEFT JOIN dbo.EDUBranch b ON app.EducationBranchId=b.EDUBranchId
Run Code Online (Sandbox Code Playgroud)

它的查询计划:https : //www.brentozar.com/pastetheplan/?id=H1cFQxwdP

更改连接顺序后:

SELECT TOP 100 * FROM dbo.APP App
LEFT JOIN dbo.EDUBranch b ON app.EducationBranchId=b.EDUBranchId
JOIN dbo.PRS p ON App.PartyId=p.PRSId
LEFT JOIN dbo.Country ON p.NationalityId = dbo.Country.CountryId
Run Code Online (Sandbox Code Playgroud)

它的查询计划:https : //www.brentozar.com/pastetheplan/?id=SJv1GlPdv

有没有人知道

  1. 为什么自适应连接会导致查询变慢?
  2. 改变连接顺序如何改变执行计划?

Jos*_*ell 7

快速计划有一个连续目标。这最终有利于嵌套循环连接,它相当快地将 100 行传送到 Top 运算符,满足查询。

慢速计划也有一个行目标,但实际上只在自适应连接运算符上。在自适应连接需要作为散列连接运行的情况下,必须消耗来自上层输入的所有结果(散列连接的“构建”步骤)。请参阅 Forrest McDaniel 的博客,了解其工作原理:三个物理连接,可视化

为什么自适应连接会导致查询变慢?

自适应加盟实际上运行的哈希联接,因为它超过了88行的阈值(用了不少)。根据执行计划,这导致查询必须从 读取每一行dbo.APP,从dbo.PRS大约 30 GB 的读取中加入所有匹配项。

改变连接顺序如何改变执行计划?

优化器能够对连接重新排序,以便更早、更有效地过滤结果集,只要查询仍会产生正确的结果。但是面对 OUTER 和 INNER 连接的混合,它并没有这样做。有关详细信息,请参阅此问答:内部连接消除被先前外部连接抑制

当您手动重写连接顺序时,它允许在连接dbo.EDUBranch之前加入的计划dbo.Country- 它没有自适应连接,利用上面提到的行目标,结果好得多(如您所见)。