SQL查询速度。比较查询1和查询2

SQL查询速度。比较查询1和查询2,sql,Sql,我有以下两个示例查询。为什么第一个比第二个慢那么多?其中CustomerTable是所有客户的列表,即客户名称、客户编号、客户地址、电话、电子邮件等 RevenueTable包含所有发票交易,customerNo作为外键 问题1 SELECT c.CustomerName, c.CustomerNumber, SUM(Amount) as TotalAmount FROM CustomerTable c LEFT JOIN RevenueTable r ON c.Cu

我有以下两个示例查询。为什么第一个比第二个慢那么多?其中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

由于GROUP BY,第二个查询在左侧联接中的数据将更少。

您说“…revenueTable中的总行数比customer表大得多”。假设revenueTable是某种交易或销售表,这是有意义的(一个客户可能会-希望-进行多个交易)

因此,正如一匹没有名字的马所建议的那样,检查执行计划

让我们把一些数字放在表格上。假设客户有1000行,而revenueTable有1000000行,那么查询1将把所有客户加入revenueTable,即将1000个客户扩展到1000000条与每个revenueTable记录对齐的记录。然后把它们全部加起来

第二个查询将首先将所有金额相加(即,将1000000条记录折叠为1000条记录-因为有1000个客户)。然后连接是1000到1000条记录(与查询1中的1000到1000000条记录连接相反)

希望您可以看到,查询1将1000个客户扩展到1000000个收入记录,然后对新的更大的1000000个记录求和,这比首先将1000000个收入记录压缩到1000个,然后将1000个收入记录合并到1000个客户记录要复杂得多

再次,检查执行计划以确定到底发生了什么,根据提供的信息,这只是我的最佳猜测


顺便说一句,我忽略了外部连接,但是如果考虑到一些客户没有收入记录的可能性,基本原则仍然是一样的。这只是意味着查询2将把1000000个收入记录折叠成一些甚至低于1000个的记录-取决于有多少客户没有收入记录(例如,100个客户没有收入记录,查询2中的内部查询将生成900条记录)。

检查许多原因、表的大小、索引、键等。如上所述,检查执行计划一种可能性是,在第二次查询中,
JOIN
to的数据集[可能]小得多。但正如所建议的,您的第一站应该是检查执行计划。您确定它的数据相同吗?在查询之间的revenueTable中使用了不同的字段:CustomerNo与CustomerNumber?第二站基本上是一个内部连接,在
Total
上执行空检查。可能会导致不同的查询计划,这比ore优化。我个人会用第三种方式写这篇文章,借用第一个查询,但在窗口函数上有一个内部联接和一个SUM()。@Al_1999如果这对您有帮助,请您接受答案(单击答案旁边的灰色复选标记)并进行投票。谢谢。