分组使用临时;使用filesort

时间:2016-05-31 08:44:37

标签: mysql

我最近有一个旧项目要维护(我不是一个经验丰富的开发人员),我找到了这样的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 '。我认为'组是由'条款引起了这个问题。
所以,我想知道我是否可以用另一种方式优化或重写它。这将给我相同的功能,并避免额外的排序东西。
任何帮助都会对我糟糕的英语表示赞赏和抱歉。

order_goods的索引:
order_id,goods_id ......

order_info的索引:
order_id,order_status,shipping_status ...

解释输出在这里:

enter image description here

1 个答案:

答案 0 :(得分:0)

我建议改变

WHERE o.order_status in (1,5,6)

代表

WHERE (o.order_status = 1 OR o.order_status = 5 OR o.order_status = 6)

不应该改变太多......但是我知道在一些mysql版本中速度很慢,也取决于你在两个表中都有的记录。

您也可以从选择句子中更改if,而不是在每一行中执行if,您可以在只获取状态为0,3,5的行的地方使用它,并按发货状态添加组。 / p>

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

注意你不会得到与预期相同的结果,但我认为这是获得结果的最佳方式,也许改变你的代码并不是那么难。

尝试执行此操作,让我们看看时间如何;)