MySQL 在 ANSI SQL92 基礎上擴展了優化器提示、結果導出、分組過濾等強大功能。本文系統拆解每個子句的語法、語義與實戰陷阱。
SELECT [STRAIGHT_JOIN] [SQL_SMALL_RESULT] [SQL_BIG_RESULT] [HIGH_PRIORITY]
[DISTINCT | DISTINCTROW | ALL] select_list
[INTO {OUTFILE | DUMPFILE} 'file_name' export_options]
[FROM table_references
[WHERE where_definition]
[GROUP BY col_name,... [WITH ROLLUP]]
[HAVING where_definition]
[ORDER BY {col_name | expr | position} [ASC | DESC],...]
[LIMIT [offset,] rows]
[PROCEDURE procedure_name]]
| 關鍵字 | 作用 | 適用場景 | 風險 |
|---|---|---|---|
STRAIGHT_JOIN | 強制按 FROM 順序連表 | 優化器選錯連接順序導致慢查詢 | 可能阻礙更優計劃,慎用 |
SQL_SMALL_RESULT | 結果集小,用臨時表而非排序 | GROUP BY/DISTINCT 結果確定很小 | 估算錯誤反而拖慢 |
SQL_BIG_RESULT | 結果集大,用排序而非臨時表 | 大結果集 GROUP BY/DISTINCT | 同左 |
HIGH_PRIORITY | 提升 SELECT 優先級超過 UPDATE | 關鍵報表查詢插隊 | 可能阻塞寫入,影響業務 |
實戰建議:絕大多數場景不需要這四個提示。優化器足夠智能,僅在 EXPLAIN 確認計劃確有問題且無索引優化空間時,作為最後手段嘗試。
DISTINCT / DISTINCTROW:結果集去重,**NULL 視為相等**(多個 NULL 只保留一行)ALL:默認行為,保留所有行,無任何效果,純兼容性保留export_options 語法同 LOAD DATA INFILE 的 FIELDS/LINES 子句OUTFILE:正常導出,含列/行結束符DUMPFILE:僅寫入單行原始數據,無任何分隔符(適合導出二進制/BLOB)*:按 CREATE TABLE 順序所有列col_name AS alias:別名SELECT t1.name, t2.salary FROM employee AS t1, info AS t2 WHERE t1.name = t2.name
-- 等價於
SELECT t1.name, t2.salary FROM employee t1, info t2 WHERE t1.name = t2.name
[NOT] expression comparison_operator expression
[NOT] expression [NOT] LIKE "pattern"
[NOT] expression IS [NOT] NULL
[NOT] expression [NOT] BETWEEN expr AND expr
[NOT] column_name join_operator column_name
[NOT] boolean_expression
AND(最高)OR| 符號 | 含義 |
|---|---|
| = | 等於 |
| > / < | 大於 / 小於 |
| >= / <= | 大於等於 / 小於等於 |
| != / <> | 不等於 |
< 更接近字母表頭,**小寫 > 大寫 > 數字**(依賴校對規則)'Dirk' = 'Dirk '< 早於,> 晚於| 符號 | 含義 |
|---|---|
| % | 任意長度字符串(含空串) |
| _ | 任意單字符 |
DATETIME 查詢技巧:完整時間含秒/毫秒,精確等值難命中。用
WHERE arrival_time LIKE '%9:20%'模糊匹配時分。
GROUP BY [ALL] aggregate_free_expression [, ...]
[HAVING search_conditions]
GROUP BY:按表達式分組,SELECT 列表可用聚合函數ALL:包含 WHERE 過濾掉的組(Transact-SQL 擴展),與 HAVING 共用時失效aggregate_free_expression:不含聚合函數的表達式(擴展允許)HAVING:分組後過濾,**可引用聚合函數**,語法同 WHEREASC(默認升序)、DESC(降序)SELECT id AS myid FROM t GROUP BY myid 等價於 GROUP BY id / GROUP BY 1LIMIT n ≡ LIMIT 0, n:前 n 行LIMIT offset, n:跳過 offset 行,取 n 行(**offset 從 0 開始**)LIMIT 1000000, 10 需掃描 100 萬行。優化:WHERE id > last_max_id LIMIT 10(游標分頁)歷史遺留擴展,用於結果集後處理(如 ANALYSE() 建議優化列類型)。MySQL 8.0 移除,現代版本不建議使用。