我正在尝试确定这是报告错误的执行计划还是按预期工作的实际功能。
在我的执行计划中,当使用 MAXDOP 1 时,我看到整个表正在被扫描(https://www.brentozar.com/pastetheplan/?id=HkPFquLdc - 计划对象 11 的最底部显示读取了大约 250 万行整个表)。
但是,当我让引擎在没有提示的情况下选择它自己的计划时,它会并行(https://www.brentozar.com/pastetheplan/?id=r12p5OUdc)并进行位图/哈希匹配,并且相同的 Object11 只显示〜尽管进行了索引扫描并且在不在聚集索引中的其他列上有一堆谓词,但仍读取了 534k 行。
我希望 SQL 必须读取表中的每一行来评估每个谓词,但也许并行计划中对象 11 上的 PROBE IN(您在粘贴计划中看不到这一点)能够“过滤掉页面" 因为探头在 PK/CX 上。
这是一个按预期工作的功能。在并行行模式计划中,SQL Server 可以在哈希连接的构建输入上引入位图构建,以粗略跟踪它遇到的连接键。当散列连接从构建其散列表过渡到探测第二个输入的匹配时,位图被传输到探测端并尽可能地向下推计划的那个分支。
这种技术被称为早期半连接减少。近似位图用于过滤掉不可能连接的行。在最好的情况下,位图可以一直向下推到探测分支,直到数据访问方法,然后执行
INROW
。应用优化时
INROW
,存储引擎会在读取页面时应用减小大小的位图。通过此过滤器的任何行都将呈现给查询处理器,该处理器在应用扫描或查找的任何残留谓词之前应用完整大小的位图(可能会消除更多行)。只有通过位图测试和剩余谓词的行才会离开查找或扫描运算符。更多细节在我的文章中: