我在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`
请建议我可以对此查询进行任何优化。它已经正确索引了所需的列。
答案 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