SELECT 是 SQL 最核心、變化最多的指令。MySQL 在 ANSI SQL-92 基礎上擴展了多項實用選項。本文系統梳理完整語法、各子句用法與效能技巧。
SELECT
[ALL | DISTINCT | DISTINCTROW]
[HIGH_PRIORITY]
[STRAIGHT_JOIN]
[SQL_SMALL_RESULT | SQL_BIG_RESULT]
[SQL_BUFFER_RESULT]
[SQL_CACHE | SQL_NO_CACHE]
[SQL_CALC_FOUND_ROWS]
select_expr [, select_expr ...]
[FROM table_references
[WHERE where_condition]
[GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]
[HAVING where_condition]
[WINDOW window_name AS (window_spec) ...]
[ORDER BY {col_name | expr | position} [ASC | DESC], ...]
[LIMIT {[offset,] row_count | row_count OFFSET offset}]
[INTO OUTFILE 'file_name' [CHARACTER SET charset_name] export_options
| INTO DUMPFILE 'file_name'
| INTO var_name [, var_name] ...]
[FOR UPDATE | LOCK IN SHARE MODE]
[NOWAIT | SKIP LOCKED]]
ALL (預設):保留所有列,含重複DISTINCT:移除完全重複的列,NULL 視為相等DISTINCTROW:同 DISTINCT,MySQL 延伸| 選項 | 用途 | 適用場景 |
|---|---|---|
STRAIGHT_JOIN | 強制按 FROM 順序 JOIN | 優化器選錯驅動表時 |
SQL_SMALL_RESULT | 結果集小,用臨時表 | GROUP BY/DISTINCT 結果確定較小 |
SQL_BIG_RESULT | 結果集大,用排序 | GROUP BY/DISTINCT 結果較大 |
SQL_BUFFER_RESULT | 結果存入臨時表釋放鎖 | 長時間傳輸結果、減少鎖持有 |
SQL_CACHE / SQL_NO_CACHE | 控制查詢快取 (已移除 8.0) | 5.7 明確控制 |
SQL_CALC_FOUND_ROWS | 配合 FOUND_ROWS() 取總數 | 分頁查詢總筆數 (8.0 建議改 COUNT 獨立查詢) |
| 錯誤寫法 | 問題 | 正確寫法 |
|---|---|---|
WHERE name = NULL | = NULL 永遠為 UNKNOWN | WHERE name IS NULL |
GROUP BY name HAVING COUNT(*) > 1 | 未聚合欄位非功能相依 (ONLY_FULL_GROUP_BY) | GROUP BY name HAVING COUNT(*) > 1 (name 在 GROUP BY 中) |
ORDER BY RAND() LIMIT 1 | 全表排序極慢 | 參考「隨機查詢優化」文章 |
SELECT * FROM t1, t2 WHERE t1.id = t2.id | 隱式 CROSS JOIN 易寫錯 | SELECT t1.a, t2.b FROM t1 JOIN t2 ON t1.id = t2.id |
SELECT 語句看似簡單,實則變化無窮。掌握核心選項、進階子句與效能技巧,能寫出既正確又高效的查詢。