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;
幾個思路:分析執行計劃(解釋查詢);指數;子查詢而不是左連接。 –
克里斯托克斯,你檢查我的答案嗎? –