[英]Need a way to optimize the slow SQL Query?
我正在mySQL服务器上运行更新查询/子查询,它需要12分钟才能完成,我认为它的优化程度不够。
有人可以考虑对其进行优化,使其运行更快吗?
提前致谢。
UPDATE `TABLE_1` C
INNER JOIN(
SELECT Cust_No,
#current year sales
(SELECT SUM(`Sales`)
FROM `TABLE_2`
WHERE Year = 2016
AND Cust_No = p.Cust_No
) as CY_TOTAL_SALES,
# Get previou year sales
(SELECT SUM(`Sales`)
FROM `TABLE_2`
WHERE Year = 2015
AND Cust_No = p.Cust_No
) as PY_TOTAL_SALES
FROM `TABLE_2` p
WHERE Year >= 2015
AND Year <= 2016
) AS A ON C.`customer_number` = A.Cust_No
SET C.CY_TOTAL_SALES = A.CY_TOTAL_SALES,
C.PY_TOTAL_SALES = A.PY_TOTAL_SALES;
TABLE_1包含28,000条记录(customer_number字段是唯一的并且已建立索引)
TABLE_2包含250,000条记录(Cust_No不是唯一的,但已建立索引)
它的作用是通过加入Table_2来更新TABLE_1,并使用子查询来汇总TABLE_2中两个年度的总销售值,然后将该值更新回TABLE_1,其中TABLE_1的客户编号与TABLE_2 Cust_no相匹配。
我可以想到几种可能的解决方案。
方法一
仅执行一个子查询,不执行任何相关的子查询,并根据年份有条件地求和。
UPDATE TABLE_1 C
INNER JOIN (
SELECT Cust_No,
SUM(IF(Year=2015, Sales, 0)) AS PY_TOTAL_SALES,
SUM(IF(Year=2016, Sales, 0)) AS CY_TOTAL_SALES
FROM TABLE_2
WHERE Year IN (2015, 2016)
GROUP BY Cust_No
) AS S ON C.customer_number = S.Cust_No
SET C.PY_TOTAL_SALES = S.PY_TOTAL_SALES,
C.CY_TOTAL_SALES = S.CY_TOTAL_SALES;
方法二
完全不执行子查询。
首先,将所有客户的总销售额归零:
UPDATE TABLE_1 C
SET C.CY_TOTAL_SALES = 0,
C.PY_TOTAL_SALES = 0;
然后进行联接而不使用任何子查询或SUM()
调用,并将每个销售数字一次添加到客户的总销售中。
UPDATE TABLE_1 AS C
INNER JOIN TABLE_2 AS S ON C.customer_number = S.Cust_No
SET C.CY_TOTAL_SALES = C.CY_TOTAL_SALES + IF(S.Year=2016, S.Sales, 0)
C.PY_TOTAL_SALES = C.PY_TOTAL_SALES + IF(S.Year=2015, S.Sales, 0)
WHERE S.Year IN (2015, 2016);
对于这两种解决方案,您都希望在TABLE_2列(Cust_No,Year,Sales)上建立索引。
同时,我可以解释一下您原始查询为何如此缓慢的原因。 您的子查询读取TABLE_2,您说它有250,000行(我假设所有行都在2015-2016年),并为每一行计算相应客户的总销售额。 这意味着它将为每个客户多次计算相同的总和。
您正在运行500,000个相关子查询! 这实际上是一个奇迹,只需要12分钟。
这样做时,由于有子查询,它会将整个结果保存在250,000行的临时表中。
然后,它将临时表连接到TABLE_1,并为每个客户设置CY_TOTAL_SALES和PY_TOTAL_SALES。 您不知道,但是它为每个客户多次设置相同的总数。
由于新用户的声誉,无法添加评论。
如果不查看表结构和当前索引,将很难判断如何优化当前查询。 请编辑您的问题以包括表结构( show create table
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.