我有以下两个示例查询。为什么第一个比第二个慢很多?其中CustomerTable是所有客户的列表,即客户名称,客户编号,客户地址,电话,电子邮件等。
RevenueTable包含所有发票交易,并将customerNo作为外键。
查询1
SELECT c.CustomerName, c.CustomerNumber, SUM(Amount) as TotalAmount
FROM CustomerTable c LEFT JOIN
RevenueTable r
ON c.CustomerNumber = r.CustomerNumber
GROUP BY c.CustomerName, c.CustomerNumber
查询2
SELECT c.CustomerNumber,CustomerName, Total
FROM CustomerTable c LEFT JOIN
(SELECT CUstomerNumber, SUM(Amount) as Total
FROM revenueTable r
GROUP BY CustomerNumber
) r
ON c.CustomerNumber = r.CustomerNumber
WHERE Total IS NOT NULL
答案 0 :(得分:0)
您说“ ...收益表中的总行数要比顾客表大得多”。假设RevenueTable是某种交易或销售表,这将是有道理的(客户希望-希望进行多笔交易)。
因此,按照建议的 a_horse_with_no_name ,检查执行计划。
让我们在表格大小上加上一些数字。假设客户有1000行,而收益表有1000000行,则查询1将所有客户加入收益表,即将1,000个客户扩展到与每个收益表记录对齐的1,000,000条记录。然后将它们全部加起来。
第二个查询将首先累加所有金额(即将1,000,000条记录折叠为1,000条记录-因为有1,000个客户)。那么联接是1,000到1,000条记录(与查询1中的1,000到1,000,000条记录相反)。
希望您能看到查询1将1,000个客户扩展到1,000,000个收入记录,然后将新的较大的1,000,000个记录相加,比首先将1,000,000个收入记录折叠成1,000个然后再合并这1,000个收入记录要多到1000条客户记录。
再次,检查执行计划以确定确切的情况,这只是根据所提供信息的最佳猜测。
顺便说一句。我忽略了OUTER JOIN,但是如果您允许某些客户没有收入记录的可能性,则基本原理仍然相同。这仅意味着查询2将把1,000,000个收入记录折叠成甚至少于1,000的记录数量-取决于有多少客户没有收入记录(例如100个客户没有收入记录,查询2中的内部查询将生成900条记录)。
答案 1 :(得分:-1)
由于GROUP BY,第二个查询在LEFT JOIN中的数据将更少。