为什么简单LEFT JOIN的执行计划会出现SORT操作?如何消除该操作?
LEFT JOIN查询出现SORT操作的原因及解决方案
SORT操作出现的原因
你当前创建的test非聚集索引仅将orderdate作为索引键列,查询时首先通过该索引筛选出orderdate在指定范围内的订单数据,此时返回的订单数据集是按照orderdate排序的,并非按照和customers表的关联键CustomerId排序。
执行计划选择了合并连接作为orders表和customers表的关联方式,合并连接的必要前提是两个关联的输入数据集都按照关联键排序,因此优化器自动添加了SORT操作,将订单数据集先按CustomerId排序后再进行关联,这就是SORT操作的来源。
可行解决方案
- 调整test索引结构(最优方案)
将CustomerId添加到索引键列中,修改后的索引定义如下:
调整后,符合create nonclustered index test on orders ([orderdate], [CustomerId]) include ( [OutletId],[OrderNumber],[OrderReference],[ServerId],[CashierId],[RegisterId])orderdate筛选条件的订单数据在索引中已经按照CustomerId有序排列,不需要额外执行SORT操作即可直接走合并连接。 - 强制使用嵌套循环连接
如果符合筛选条件的订单数据量较小,可以强制关联方式为嵌套循环,该关联方式不需要数据集按关联键排序,修改关联语句即可:
注意该方案仅适合小结果集场景,若订单数据量较大,嵌套循环的性能会低于带排序的合并连接。left loop join customers c on o.CustomerId = c.CustomerId - 更新统计信息或引导使用哈希连接
首先可以尝试更新表统计信息,避免统计信息过时导致优化器选错关联方式:
如果是大结果集关联场景,也可以引导优化器使用哈希连接,哈希连接不需要对数据集排序:update statistics orders; update statistics customers;left hash join customers c on o.CustomerId = c.CustomerId
内容的提问来源于stack exchange,提问作者Atoli Gaming
相关产品推荐
相关产品推荐

