| 類型 | 語法 | 語義 | 適用場景 |
|---|---|---|---|
| 交叉連接 | CROSS JOIN / JOIN / , | 笛卡爾積 M×N | 極少用,需配合 WHERE/ON 過濾 |
| 內連接 | INNER JOIN | 等值連接,僅保留匹配行 | 最常用,優化器可自由調整順序 |
| 左外連接 | LEFT [OUTER] JOIN | 保留左表所有行 | 主表查詢從表詳情,允許無匹配 |
| 右外連接 | RIGHT [OUTER] JOIN | 保留右表所有行 | 較少用,可改寫為 LEFT JOIN |
SELECT id, name, action
FROM user AS u
LEFT JOIN user_action a ON u.id = a.user_id;
結果集:
| id | name | action |
|---|---|---|
| 1 | libk | jump |
| 1 | libk | kick |
| 1 | libk | jump |
| 2 | zyfon | run |
| 3 | daodao | NULL |
右表 user_id=4 無左表匹配被丟棄;左表 id=3 無右表匹配保留並 NULL 填充。
SELECT u.id, u.name
FROM user AS u
LEFT JOIN user_action a ON u.id = a.user_id
WHERE a.user_id IS NULL; -- 必須用 IS NULL,且判斷列定義為 NOT NULL
col IS NULL(col 為 NOT NULL),匹配到第一行即停止搜索。優化器自動決定連接順序。LEFT JOIN 與 STRAIGHT_JOIN 會強制表讀取順序,減少優化器排列組合開銷。
-- 低效:強制先讀 a,再左連 b,導致 b 全掃描
SELECT * FROM a, b LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key) WHERE b.key=d.key;
-- 優化:調整 FROM 順序,b 先讀
SELECT * FROM b, a LEFT JOIN c ON (c.key=a.key) LEFT JOIN d ON (d.key=a.key) WHERE b.key=d.key;
若 WHERE 條件對 NULL 行永假,外連接退化為內連接,優化器可自由調序:
-- 原查詢
SELECT * FROM t1 LEFT JOIN t2 ON (t1.column1 = t2.column1) WHERE t2.column2 = 5;
-- t2.column2=5 對 NULL 永假,等價於內連接
SELECT * FROM t1, t2 WHERE t2.column2 = 5 AND t1.column1 = t2.column1;
| 場景 | 推薦寫法 | 理由 |
|---|---|---|
| 同名列連接 | USING (col) | 結果集自動去重,語義清晰 |
| 通用條件 | ON t1.col = t2.col | 標準 SQL,靈活支持複合條件 |
| 業務過濾 | WHERE ... | 連接完成後過濾,不影響連接語義 |
join_buffer_size;type=ref/eq_ref、rows 預估、Extra=Using where; Using join buffer;