有什么办法可以优化下面的查询吗?

时间:2015-10-12 10:11:45

标签: mysql optimization group-by

我在MySQL中有以下查询。它显示mysql服务器消失了。查询有什么问题?

SELECT Customer.id,
       Customer.first_name,
       Customer.last_name,
       Sum(Sale.`cal_qty`) AS totPurchase,
       Sale2.tot2          AS totPurchase2
FROM   `customers` AS Customer
       LEFT JOIN `sales` AS Sale
              ON Sale.customer_id = Customer.id
       LEFT JOIN (SELECT s2.customer_id  AS customer_id,
                         Sum(s2.cal_qty) AS tot2
                  FROM   sales AS s2
                  WHERE  s2.sale_date BETWEEN '2015-08-13' AND '2015-09-11'
                  GROUP  BY s2.customer_id) AS Sale2
              ON Sale.customer_id = Sale2.customer_id
WHERE  Sale.sale_date BETWEEN '2015-09-12' AND '2015-10-12'
GROUP  BY Sale.`customer_id`

请建议我可以对此查询进行任何优化。它已经正确索引了所需的列。

2 个答案:

答案 0 :(得分:0)

请提供SHOW CREATE TABLE

请解释LEFT的必要性。如果你不能,那就去掉LEFT

添加以下索引:

INDEX(sale_date)
INDEX(customer_id, sale_date)

答案 1 :(得分:0)

首先,您的WHERE子句限定了SALE表,从而将其转换为JOIN与LEFT JOIN。由于这是您的标准的主要基础,因此我会调整查询(并缩短别名),从而处于领先的FROM位置

对于索引优化,单个索引应该在WHERE AND GROUP by上,但也可以包含JOIN中可以使用的任何列。

销售表...... index on(sale_date,customer_id,cal_qty)

这将按客户分组的日期优化销售活动的外部和内部查询。有一个"覆盖"包含Cal_Qty字段的索引可以防止需要返回查询的原始数据页。它可以直接从索引组件中完成所有需要。

Customer表应该有一个索引ON(id),因为它将是该表连接的主键。

SELECT 
      C.id,
      C.first_name,
      C.last_name,
      Sum(S.cal_qty) AS totPurchase,
      Sale2.tot2 AS totPurchase2
   FROM   
      sales S
         JOIN customers AS C
            ON S.customer_id = C.id
         LEFT JOIN ( SELECT 
                           s2.customer_id  AS customer_id,
                           Sum(s2.cal_qty) AS tot2
                        FROM   
                           sales AS s2
                        WHERE  
                           s2.sale_date BETWEEN '2015-08-13' AND '2015-09-11'
                        GROUP BY 
                           s2.customer_id ) AS Sale2
            ON S.customer_id = Sale2.customer_id
   WHERE  
      S.sale_date BETWEEN '2015-09-12' AND '2015-10-12'
   GROUP BY 
      S.customer_id