MySQL似乎无法使用GROUP BY子查询来优化选择,并且以较长的执行时间结束。对于这种常见的情况必须有一个已知的优化。与左右连接组合的MySQL子查询 - 优化
假设我们试图从数据库返回所有订单,并带有一个标志,指示它是否是客户的第一笔订单。
CREATE TABLE orders (order int, customer int, date date);
检索客户的第一个订单是超快。
SELECT customer, min(order) as first_order FROM orders GROUP BY customer;
然而,一旦我们使用子查询
SELECT order, first_order FROM orders LEFT JOIN (
SELECT customer, min(order) as first_order FROM orders GROUP BY customer
) AS first_orders ON orders.order=first_orders.first_order;
我希望有我们缺少一个简单的一招加入这个与全单组就变得很慢,因为否则的话将约1000倍快做
CREATE TEMPORARY TABLE tmp_first_order AS
SELECT customer, min(order) as first_order FROM orders GROUP BY customer;
CREATE INDEX tmp_boost ON tmp_first_order (first_order)
SELECT order, first_order FROM orders LEFT JOIN tmp_first_order
ON orders.order=tmp_first_order.first_order;
编辑:
通过@ruakh启发提出d选项3,使用INNER JOIN
和UNION
确实有一个不太难看的解决方法,它具有可接受的性能,但不需要临时表。但是,这是有点特定于我们的情况,我想知道是否存在更通用的优化。
SELECT order, "YES" as first FROM orders INNER JOIN (
SELECT min(order) as first_order FROM orders GROUP BY customer
) AS first_orders_1 ON orders.order=first_orders_1.first_order
UNION
SELECT order, "NO" as first FROM orders INNER JOIN (
SELECT customer, min(order) as first_order FROM orders GROUP BY customer
) AS first_orders_2 ON first_orders_2.customer = orders.customer
AND orders.order > first_orders_2.first_order;
几个思路:分析执行计划(解释查询);指数;子查询而不是左连接。 –
克里斯托克斯,你检查我的答案吗? –