[英]Group by causing using temporary; using filesort
我最近有一个旧项目要维护(我不是一个经验丰富的开发人员),我发现了这样的SQL:
SELECT
g.goods_id, o.order_status,
SUM(IF(o.shipping_status=0, g.quantity, 0)) AS 'pending',
SUM(IF(o.shipping_status=3, g.quantity, 0)) AS 'picking',
SUM(IF(o.shipping_status=5, g.quantity, 0)) AS 'shipping'
FROM
order_info AS o
LEFT JOIN
order_goods AS g ON g.order_id = o.order_id
WHERE o.order_status in (1,5,6)
GROUP BY g.goods_id
我删除了一些烦人的东西,所以看起来更干净了。 但是,我花了大约10秒钟才得到结果。
该数据库只有6万行记录。 它具有所需的所有索引。
而且explain命令显示SQL是“ 使用临时; 使用filesort '。 我认为“ group by”子句引起了问题。
因此,我想知道是否可以用其他方式优化或重写它。 这将为我提供相同的功能,并且都避免了多余的排序工作。
对于我的英语不好,我们将不胜感激。
order_goods的索引:
order_id,goods_id ...
order_info的索引:
order_id,order_status,shipping_status ...
说明输出在这里:
我建议改变
WHERE o.order_status in (1,5,6)
对于
WHERE (o.order_status = 1 OR o.order_status = 5 OR o.order_status = 6)
不应该改变太多...但是我知道在某些mysql版本中in相当慢,这还取决于您在两个表中的记录。
您还可以从选择语句中更改if,而不是在每行中执行if,而可以在仅获取状态为0、3、5的行并按装运状态添加组的情况下使用if。
AND (o.shipping_status = 0 OR o.order_status = 3 OR o.order_status = 5)
所有句子连续
SELECT
g.goods_id, o.order_status,
SUM(g.quantity) AS 'quantity'
FROM
order_info AS o
LEFT JOIN
order_goods AS g ON g.order_id = o.order_id
WHERE (o.order_status = 1 OR o.order_status = 5 OR o.order_status = 6) AND
(o.shipping_status = 0 OR o.shipping_status = 3 OR o.shipping_status = 5)
GROUP BY g.goods_id,o.shipping_status
请注意,您不会得到与预期相同的结果,但是我认为这是获得结果的快速方法,也许更改您的代码并不难。
尝试执行此操作,让我们看看时代如何发展;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.