通过 MySQL 查询优化组
Optimizing a group by MySQL query
我有一个 orders
table 可以连续保存一个用户订单的一个项目。因此每个用户都可以出现在多行中。每个订单行都有一个状态 - PENDING
、APPROVED
等等。我想为每个用户计算每个状态的订单数量,即有多少订单已获批准,有多少仍待处理等等。我提出了以下查询:
SELECT
u.email, u.id,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'PENDING') pending,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'APPROVED') approved,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'REJECTED') rejected,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'ERROR') error
FROM orders o INNER JOIN users u ON o.user_id = u.id
GROUP BY o.user_id, u.email
问题是速度太慢了!我在 orders
table 中有大约 5000 条记录,执行起来只需几分钟。请教如何优化。
您可以使用条件聚合摆脱子查询:
SELECT
u.email, u.id,
COUNT(CASE WHEN status = 'PENDING' THEN 1 END) pending,
COUNT(CASE WHEN status = 'APPROVED' THEN 1 END) approved,
COUNT(CASE WHEN status = 'REJECTED' THEN 1 END) rejected,
COUNT(CASE WHEN status = 'ERROR' THEN 1 END) error
FROM orders o INNER JOIN users u ON o.user_id = u.id
GROUP BY o.user_id, u.email
实际上不确定您是否需要分组依据:
SELECT u.email, u.id,o.pending,o.approved,o.rejected,o.error
FROM users u INNER JOIN
(
SELECT
user_id,
COUNT(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) pending,
COUNT(CASE WHEN status = 'APPROVED' THEN 1 ELSE 0 END) approved,
COUNT(CASE WHEN status = 'REJECTED' THEN 1 ELSE 0 END) rejected,
COUNT(CASE WHEN status = 'ERROR' THEN 1 ELSE 0 END) error
FROM orders
) o
ON u.id = o.user_id
我有一个 orders
table 可以连续保存一个用户订单的一个项目。因此每个用户都可以出现在多行中。每个订单行都有一个状态 - PENDING
、APPROVED
等等。我想为每个用户计算每个状态的订单数量,即有多少订单已获批准,有多少仍待处理等等。我提出了以下查询:
SELECT
u.email, u.id,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'PENDING') pending,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'APPROVED') approved,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'REJECTED') rejected,
(SELECT count(status) FROM orders WHERE user_id = o.user_id AND status = 'ERROR') error
FROM orders o INNER JOIN users u ON o.user_id = u.id
GROUP BY o.user_id, u.email
问题是速度太慢了!我在 orders
table 中有大约 5000 条记录,执行起来只需几分钟。请教如何优化。
您可以使用条件聚合摆脱子查询:
SELECT
u.email, u.id,
COUNT(CASE WHEN status = 'PENDING' THEN 1 END) pending,
COUNT(CASE WHEN status = 'APPROVED' THEN 1 END) approved,
COUNT(CASE WHEN status = 'REJECTED' THEN 1 END) rejected,
COUNT(CASE WHEN status = 'ERROR' THEN 1 END) error
FROM orders o INNER JOIN users u ON o.user_id = u.id
GROUP BY o.user_id, u.email
实际上不确定您是否需要分组依据:
SELECT u.email, u.id,o.pending,o.approved,o.rejected,o.error
FROM users u INNER JOIN
(
SELECT
user_id,
COUNT(CASE WHEN status = 'PENDING' THEN 1 ELSE 0 END) pending,
COUNT(CASE WHEN status = 'APPROVED' THEN 1 ELSE 0 END) approved,
COUNT(CASE WHEN status = 'REJECTED' THEN 1 ELSE 0 END) rejected,
COUNT(CASE WHEN status = 'ERROR' THEN 1 ELSE 0 END) error
FROM orders
) o
ON u.id = o.user_id