我最近有一个旧项目要维护(我不是一个经验丰富的开发人员),我找到了这样的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 ...
解释输出在这里:
答案 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
注意你不会得到与预期相同的结果,但我认为这是获得结果的最佳方式,也许改变你的代码并不是那么难。
尝试执行此操作,让我们看看时间如何;)