繁体   English   中英

通过使用临时分组进行分组; 使用文件排序

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM