LEFT JOIN 服务器性能优化

LEFT JOIN 服务器性能优化

我有一个查询,希望以最快的速度执行。

这里是:

select d.InvoiceDetailId,a.Fee,a.FeeTax
from InvoiceDetail d
LEFT JOIN InvoiceDetail a on a.AdjustDetailId = d.InvoiceDetailId

我在 AdjustDetailId 列上放置了一个升序索引

然后我使用“显示实际执行计划”运行查询,结果估计子树成本(最顶层选择节点)为 2.07

然后我想,也许我可以做些事情来改善这一点,所以我在左连接中添加了一个条件,如下所示:

select d.InvoiceDetailId,a.Fee,a.FeeTax
from InvoiceDetail d
LEFT JOIN InvoiceDetail a on a.AdjustDetailId is not null 
and a.AdjustDetailId = d.InvoiceDetailId

我重新运行,结果发现子树成本为 0.98。所以我想,太好了,我把它快了两倍。好吧,我接着点击了“显示客户端统计信息”,然后对两个查询点击了 4-5 次“执行”,信不信由你,第一个查询的平均速度更快。我不明白。顺便说一下,查询返回了 120K 行。

有什么见解吗?

也许我因为缓存而得到了受污染的结果,但我不知道是否是这种情况或如何重置缓存。

编辑:好的,我在谷歌上搜索了如何清除查询缓存,所以我在查询前添加了以下内容:

DBCC DROPCLEANBUFFERS  
DBCC FREEPROCCACHE

然后我运行每个查询 5 次,第一个查询仍然快一点(13%)。第一个查询:客户端处理时间:239.4 第二个查询:客户端处理时间:290

所以我想问题是,你为什么这么认为?当表的大小增加四倍时,第二个查询会更快吗?或者左连接导致查询两次命中索引,因此它总是会变慢。

请不要责骂我,我只是想学习知识。

答案1

在 AdjustDetailID 的索引中,包括 Fee 和 FeeTax 列。否则系统将需要查找以获取该数据,并且系统最终可能会进行扫描,而忽略您的索引。

相关内容