分析階段即將所有 RIGHT JOIN 依規則轉換:
(T1, ...) RIGHT JOIN (T2, ...) ON P(T1,...,T2,...)
= (T2, ...) LEFT JOIN (T1, ...) ON P(T1,...,T2,...)
內部聯接 T1 INNER JOIN T2 ON P 展開為 T1, T2, P 併入 WHERE 或嵌入聯接條件。
含外部聯接查詢時,優化器只考慮「先訪問外表、再訪問內表」的執行計畫,因為 Nested Loop 算法要求外表在外層迴圈。這縮減搜尋空間但可能錯失最佳序。
若條件對外部聯接產生的「NULL 補齊行」評估為 FALSE 或 UNKNOWN,則該條件為該外部聯接的 NULL 拒絕條件。
T2.B IS NOT NULL (內表屬性非空)T2.B > 3, T2.C <= T1.C (含內表屬性的比較)T2.B < 2 OR T2.C > 1 (析取式中任一為 NULL 拒絕)T2.B IS NULLT1.B < 3 OR T2.B IS NOT NULL (整體對 NULL 行可能為 TRUE)T1.B < 3 OR T2.B > 3A IS NOT NULL (A 為內表屬性)。OR 聯集。AND 交集。單一外部聯接轉內部聯接後,可能使上一層外部聯接的條件成為 NULL 拒絕,繼續轉換。
SELECT * FROM T1
LEFT JOIN T2 ON T2.A=T1.A
LEFT JOIN T3 ON T3.B=T2.B
WHERE T3.C > 0;
-- 步驟 1:T3.C>0 對第 2 個 LEFT JOIN 為 NULL 拒絕 → 轉 INNER JOIN
SELECT * FROM T1
LEFT JOIN T2 ON T2.A=T1.A
INNER JOIN T3 ON T3.B=T2.B
WHERE T3.C > 0;
-- 步驟 2:T3.B=T2.B 成為第 1 個 LEFT JOIN 的 NULL 拒絕 → 轉 INNER JOIN
SELECT * FROM T1
INNER JOIN T2 ON T2.A=T1.A
INNER JOIN T3 ON T3.B=T2.B
WHERE T3.C > 0;
最終無外部聯接,優化器可自由排列 T3, T1, T2 等最佳順序。
SELECT * FROM T1
LEFT JOIN (T2 LEFT JOIN T3 ON T3.B=T2.B) ON T2.A=T1.A
WHERE T3.C > 0;
-- 僅內層轉換
SELECT * FROM T1
LEFT JOIN (T2 INNER JOIN T3 ON T3.B=T2.B) ON T2.A=T1.A
WHERE T3.C > 0;
-- 重寫為單層 LEFT JOIN (仍保留外部聯接)
SELECT * FROM T1
LEFT JOIN (T2, T3) ON (T2.A=T1.A AND T3.B=T2.B)
WHERE T3.C > 0;
SELECT * FROM T1
LEFT JOIN (T2 LEFT JOIN T3 ON T3.B=T2.B) ON T2.A=T1.A AND T3.C=T1.C
WHERE T3.D > 0 OR T1.D > 0;
-- WHERE 不拒絕 NULL,但 ON 條件 T3.C=T1.C 拒絕 NULL
-- 可將 T3.B=T2.B 提升至 ON
SELECT * FROM T1
LEFT JOIN (T2, T3) ON T2.A=T1.A AND T3.C=T1.C AND T3.B=T2.B
WHERE T3.D > 0 OR T1.D > 0;
ORDER BY 可省略 Filesort。WHERE 常數填補索引前綴缺口可用索引排序。DESC 全部降序同樣可用。max_length_for_sort_data 限制。sort_buffer_size, read_rnd_buffer_size;tmpdir 指向獨立物理磁碟;GROUP BY 加 ORDER BY NULL 禁用隱含排序。