我在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 WHERE TABLE_1自定义程序编号与TABLE_2 Cust_no匹配。
答案 0 :(得分:4)
我可以想到几种可能的解决方案。
方法一
只做一个子查询,不做任何相关的子查询,并根据年份有条件地求和。
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。你不知道,但它为每个客户设置了相同的总数。
答案 1 :(得分:0)
由于新用户信誉,无法添加评论。
如果没有看到表结构,那么当前的索引将很难说明如何优化当前查询。
请修改您的问题以包含表格结构(show create table
)。