同一個關聯查詢,寫法不同卻產生完全相同的執行計畫?本文以 film / film_actor 為例,剖析 JOIN ... ON、JOIN ... USING、WHERE (Theta) 三種風格的語法差異、結果集結構差別、優化器內部轉換與最佳實踐建議。
-- 1. ANSI ON (推薦)
SELECT * FROM film
JOIN film_actor ON (film.film_id = film_actor.film_id)
WHERE actor_id = 17 AND film.length > 120;
-- 2. ANSI USING (同名欄位簡寫)
SELECT * FROM film
JOIN film_actor USING (film_id)
WHERE actor_id = 17 AND film.length > 120;
-- 3. Theta 風格 (舊式)
SELECT * FROM film, film_actor
WHERE film.film_id = film_actor.film_id
AND actor_id = 17 AND film.length > 120;
| 維度 | JOIN ... ON | JOIN ... USING | Theta (WHERE) |
|---|---|---|---|
| 關聯條件與過濾條件分離 | ✅ 清楚 | ✅ 清楚 | ❌ 混雜 |
| 同名欄位需加表前綴 | 是 | 否 (自動去重) | 是 |
| 結果集同名欄位出現次數 | 2 次 | 1 次 (合併) | 2 次 |
| SELECT * 時欄位順序 | 左表欄位在前 | USING 欄位最前 | FROM 順序 |
| 可讀性 (5 表以上) | ★★★★★ | ★★★★☆ | ★★☆☆☆ |
| 支援非等值關聯 | ✅ | ❌ (僅等值) | ✅ |
| 支援複合關聯條件 | ✅ | ✅ (USING (a,b)) | ✅ |
-- USING: film_id 僅出現 1 次
SELECT * FROM film JOIN film_actor USING (film_id) LIMIT 1\G
*************************** 1. row ***************************
film_id: 96
title: BREAKING HOME
...
actor_id: 17
last_update: 2006-02-15 05:05:03
-- ON: film_id 出現 2 次 (film.film_id, film_actor.film_id)
SELECT * FROM film JOIN film_actor ON (film.film_id = film_actor.film_id) LIMIT 1\G
*************************** 1. row ***************************
film_id: 96 -- film.film_id
...
film_id: 96 -- film_actor.film_id
actor_id: 17
...
EXPLAIN EXTENDED SELECT film.title, film_id
FROM film JOIN film_actor USING (film_id)
WHERE actor_id = 17 AND film.length > 120\G
SHOW WARNINGS\G
-- Message: select `sakila`.`film`.`title` AS `title`,
-- `sakila`.`film`.`film_id` AS `film_id`
-- from `sakila`.`film` join `sakila`.`film_actor`
-- where ( (`sakila`.`film`.`film_id` = `sakila`.`film_actor`.`film_id`)
-- and (`sakila`.`film_actor`.`actor_id` = 17)
-- and (`sakila`.`film`.`length` > 120) )
結論:三種寫法經優化器重寫後完全等價,效能零差異。選擇標準只看「團隊規範」與「可維護性」。
USING 簡化,但禁止 SELECT *,明確列出欄位避免歧義。ON (a.id = b.id AND a.type = b.type) 或 USING (id, type) 二選一,團隊統一即可。結語:語法糖不影響效能,但影響可讀性與維護成本。建立團隊「JOIN 風格指南」,統一用 JOIN ... ON,配合 EXPLAIN 驗證執行計畫,才是專業 DBA/開發者的基本功。