优化用于计算小计,折扣和每个产品总计的SQL查询

时间:2017-10-16 15:48:58

标签: mysql sql group-by query-optimization

我有一个查询,显示每件产品的销售数量,小计和总销售额之和。问题是执行时间太长。我做错了吗?我需要你的帮助来优化查询。另外,我应该用sd.Product_Id或p.Product_Name对它进行分组吗?

SELECT p.Product_Name   `Product Name`,
       SUM(sd.Quantity) `Quantity Sold`,
       SUM(sd.Subtotal) `Subtotal`,
       SUM(sd.Discount_Value) `Total Discount`,
       SUM(sd.Total)    `Total`
FROM Sales_Detail sd
JOIN Product p ON sd.Product_Id = p.Id
WHERE DATE(sd.Purchase_Date) BETWEEN DATE('2017-08-21')
                                 and date('2017-08-25')
GROUP BY p.Product_Name;

2 个答案:

答案 0 :(得分:2)

确保Sales_Detail.Purchase_Date列上有索引,然后重写查询以删除该列周围的函数,以便它可以利用索引:

SELECT p.Product_Name `Product Name`, 
  SUM(sd.Quantity) `Quantity Sold`, 
  SUM(sd.Subtotal) `Subtotal`, 
  SUM(sd.Discount_Value) `Total Discount`, 
  SUM(sd.Total) `Total`
FROM Sales_Detail sd
JOIN Product p ON sd.Product_Id = p.Id
WHERE sd.Purchase_Date >= '2017-08-21' 
  AND sd.Purchase_Date < '2017-08-26'
GROUP BY p.Product_Name;

答案 1 :(得分:0)

sd需要INDEX(Purchase_Date) 重写:

WHERE sd.Purchase_Date >= '2017-08-21'
      sd.Purchase_Date  < '2017-08-26'  -- next day

这适用于日期/日期时间等的任何风格。

这可能会更好,因为它可以避免计算傻瓜等:

WHERE sd.Purchase_Date >= '2017-08-21'
      sd.Purchase_Date  < '2017-08-21' + INTERVAL 5 DAY

另外,请考虑将GROUP BY更改为

GROUP BY sd.Product_Id

因为相同。然后,有

INDEX(Purchase_Date, Product_Id)

这将是&#34;覆盖&#34;通过使用索引(而不是后续的&#39; filesort&#39;)处理GROUP BY可能会更加优化。