Jos*_*ose 1 sql-server optimization performance
我有一个查询,我想尽快执行.
这里是:
select d.InvoiceDetailId,a.Fee,a.FeeTax
from InvoiceDetail d
LEFT JOIN InvoiceDetail a on a.AdjustDetailId = d.InvoiceDetailId
Run Code Online (Sandbox Code Playgroud)
我在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
Run Code Online (Sandbox Code Playgroud)
我重新跑了,我的子树成本为.98.所以我想,很棒,我的速度提高了两倍.然后我点击显示客户端统计信息,然后点击两次查询执行4-5次,并且相信或不相信第一个查询平均更快.我不明白.顺便说一下,查询返回120K行.
任何见解?
也许我因为缓存而得到污点,但我不知道是否是这种情况或如何重置缓存.
编辑:好的,我google了如何清除查询缓存,所以我在查询之前添加了以下内容:
DBCC DROPCLEANBUFFERS
DBCC FREEPROCCACHE
Run Code Online (Sandbox Code Playgroud)
然后我运行每个查询5次,第一个查询仍然快一点(13%).第一个查询:客户端处理时间:239.4第二个查询:客户端处理时间:290
所以我想问题是,你为什么这么认为?当表格的大小翻倍时,第二个查询会更快吗?或者左连接导致查询两次命中索引,因此它总是会变慢.
请不要激怒我,我只是想接受教育.
编辑#2:我需要获得所有的InvoiceDetails,而不仅仅是调整后的,因此左边的连接.
编辑#3:我试图用查询解决的真正问题是总结所有InvoiceDetail行,但同时也调整它们.所以最终似乎要执行的最佳查询如下.我认为做一个连接然后添加连接表将是唯一的方法,但似乎按条件分组最优雅地解决问题.
SELECT CASE WHEN AdjustDetailId IS NULL THEN InvoiceDetailId ELSE AdjustDetailId END AS InvoiceDetailId
,SUM(Fee + FeeTax) AS Fee
FROM dbo.InvoiceDetail d
GROUP BY CASE WHEN AdjustDetailId IS NULL THEN InvoiceDetailId ELSE AdjustDetailId END
Run Code Online (Sandbox Code Playgroud)
示例:使用以下行InvoiceDetailId | Fee | FeeTax | AdjustDetailId
1 | 300 | 0 | NULL
2 | -100 | 0 | 1
3 | -50 | 0 | 1
4 | 250 | 0 | NULL
我的愿望是得到以下内容:InvoiceDetailId |费用1 | 150
4 | 250
感谢大家的投入.
如果你想真正快速地进行查询,你需要
确保将InvoiceDetail.AdjustDetailId和InvoiceDetail.InvoiceDetailId编入索引
SELECT
d.InvoiceDetailId, a.Fee, a.FeeTax
FROM
dbo.InvoiceDetail d
INNER JOIN
dbo.InvoiceDetail a ON a.AdjustDetailId = d.InvoiceDetailId
Run Code Online (Sandbox Code Playgroud)接下来,您需要确保您的统计信息是最新的,以便基于成本的查询优化器可以正常工作.
要更新统计信息,请使用UPDATE STATISTICS (table)命令 - 请参阅此处有关UPDATE STATISTICS的MSDN文档