Oracle 等資料庫對子查詢優化成熟,但 MySQL 處理子查詢機制不同,易導致災難性效能。
SELECT i_id, SUM(i_sell) AS i_sell
FROM table_data
WHERE i_id IN (
SELECT i_id FROM table_data
WHERE gmt_create >= '2011-10-07 00:00:00'
)
GROUP BY i_id;
業務邏輯:先找 10/07 新售出的書,再查這些書全年的銷量。
SELECT t2.i_id, SUM(t2.i_sell) AS sold
FROM (
SELECT DISTINCT i_id
FROM table_data
WHERE gmt_create >= '2011-10-07 00:00:00'
) t1
JOIN table_data t2 ON t1.i_id = t2.i_id
GROUP BY t2.i_id;
**執行時間從數小時 → < 100ms**,效能提升 **數萬倍**。
| 場景 | 建議改寫 |
|---|---|
| IN / NOT IN 子查詢 | 改為 JOIN + DISTINCT / EXISTS |
| 標量子查詢(SELECT 列表中) | 改為 LEFT JOIN |
| FROM 子查詢(衍生表) | MySQL 5.6+ 支援衍生表合併,但仍建議显式 JOIN |
💡 核心心法:MySQL 子查詢優化器較弱,**主動改寫為 JOIN** 往往能獲得數量級效能提升。