需要一种方法来优化慢速SQL查询?

时间:2016-12-15 00:57:55

标签: mysql sql subquery

我在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匹配。

2 个答案:

答案 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)。