首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫

MySQL SELECT 查詢完全指南:從基礎語法到進階優化的實戰手冊

     編輯:MySQL 資料庫相關知識

前言:讀的藝術,始於 SELECT

SELECT 是 MySQL 使用頻率最高、變體最豐富、優化空間最大的語句。本文系統梳理完整語法結構、核心子句行為、結果導出、集合運算、去重邏輯與性能優化實戰模式,助您寫出**精準、高效、可維護**的查詢代碼。

一、完整語法結構圖譜


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, ...
    [INTO OUTFILE 'file_name' export_options | INTO DUMPFILE 'file_name']
    [FROM table_references
    [WHERE where_definition]
    [GROUP BY {col_name | expr | position} [ASC | DESC], ... [WITH ROLLUP]]
    [HAVING where_definition]
    [ORDER BY {col_name | expr | position} [ASC | DESC], ...]
    [LIMIT {[offset,] row_count | row_count OFFSET offset}]
    [PROCEDURE procedure_name(argument_list)]
    [FOR UPDATE | LOCK IN SHARE MODE]

二、核心子句深度解析與優化實戰

1. WHERE vs HAVING:過濾邊界劃分

維度WHEREHAVING
執行階段分組前、聚合前分組後、聚合後
可用列表列、衍生列分組列、聚合函數、別名
索引利用可用索引不可用索引(全掃描)
典型用法WHERE status=1HAVING COUNT(*) > 10

反模式:SELECT col FROM t HAVING col > 0 → 應改為 WHERE col > 0。

2. GROUP BY 與 WITH ROLLUP:多維聚合


-- 基礎分組
SELECT dept, COUNT(*) AS cnt FROM emp GROUP BY dept;

-- 帶排序(MySQL 5.7+ 默認不再隱式排序,需顯式 ORDER BY)
SELECT dept, COUNT(*) AS cnt FROM emp GROUP BY dept ORDER BY cnt DESC;

-- 超級聚合:小計+總計
SELECT dept, job, COUNT(*), SUM(sal) FROM emp GROUP BY dept, job WITH ROLLUP;
-- 結果包含:(dept,job)、(dept,NULL)、(NULL,NULL) 三層聚合

3. ORDER BY 多維排序技巧


-- 別名排序
SELECT college, region AS r, seed AS s FROM tournament ORDER BY r, s;

-- 位置排序(不推薦,易維護性差)
SELECT college, region, seed FROM tournament ORDER BY 2, 3;

-- 降序
SELECT a, COUNT(b) FROM test_table GROUP BY a ORDER BY a DESC;

4. LIMIT 分頁:從淺分頁到深分頁優化


-- 前 10 行
SELECT * FROM tbl LIMIT 10;           -- 等同 LIMIT 0,10

-- 第 2 頁(每頁 10 行)
SELECT * FROM tbl LIMIT 10, 10;       -- offset=10, count=10

-- 尾頁優化:大 offset 性能劣化(需掃描 offset+count 行)
-- 方案 1:延遲關聯(覆蓋索引定位主鍵再回表)
SELECT * FROM tbl INNER JOIN (SELECT id FROM tbl ORDER BY id LIMIT 100000, 10) AS t USING (id);

-- 方案 2:游標分頁(記住上頁最大 ID)
SELECT * FROM tbl WHERE id > 100000 ORDER BY id LIMIT 10;

5. SELECT ... INTO OUTFILE:高性能結果導出


SELECT a, b, a+b INTO OUTFILE '/tmp/result.txt'
FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"'
LINES TERMINATED BY '\n'
FROM test_table;
  • 文件生成在 **Server 端**,需 FILE 權限,文件不能預存在。
  • 客戶端導出請用:mysql -e "SELECT ..." > file.txt。
  • INTO DUMPFILE:單行無分隔符,適合導出 BLOB 二進制數據。

6. UNION 集合運算:去重與性能權衡


(SELECT a FROM t WHERE a=10) UNION (SELECT a FROM t WHERE a=11) ORDER BY a LIMIT 10;
類型行為性能
UNION / UNION DISTINCT去重(全局排序/哈希)慢,臨時表開銷大
UNION ALL保留重複,直接拼接快,流式輸出

原則:業務允許重複或已知無重複時,**強制用 UNION ALL**。

7. DISTINCT 去重:代價與替代方案


SELECT DISTINCT a FROM t;
SELECT COUNT(DISTINCT a) FROM t;
  • DISTINCT = DISTINCTROW,觸發臨時表+排序/哈希去重。
  • 大數據集去重考慮:GROUP BY(可用索引)、應用層去重、HyperLogLog 估算。

三、查詢優化器提示:用好也能成毒

提示作用慎用場景
SQL_CACHE / SQL_NO_CACHE控制 Query Cache 行為Query Cache 已棄用/禁用
SQL_SMALL_RESULT結果集小,用臨時表/內存表優化器通常能自動判斷
SQL_BIG_RESULT結果集大,用磁盤臨時表同左
SQL_BUFFER_RESULT強制結果放入臨時表,釋放鎖長查詢阻塞寫入時
SQL_CALC_FOUND_ROWS配合 FOUND_ROWS() 獲取無 LIMIT 總行數全表掃描開銷大,分頁建議改用 COUNT(*) 獨立查詢
STRAIGHT_JOIN強制按 FROM 順序連接優化器選錯連接順序時(極少見)
HIGH_PRIORITY提升查詢優先級(MyISAM)InnoDB 無效

四、鎖與一致性讀控制


-- 當前讀(加排他鎖,阻塞其他寫/當前讀)
SELECT * FROM t WHERE id=1 FOR UPDATE;

-- 當前讀(加共享鎖,阻塞寫,允許其他共享鎖)
SELECT * FROM t WHERE id=1 LOCK IN SHARE MODE;

-- 快照讀(MVCC,無鎖,讀已提交/可重複讀隔離級別下)
SELECT * FROM t WHERE id=1;

原則:業務允許下**優先快照讀**,必要時用最小範圍、最短持有時間的當前讀。

五、實戰優化檢查清單

  1. EXPLAIN 首檢:關注 type (ALL/index/range/ref/eq_ref/const/system)、key、rows、Extra (Using where/Using index/Using temporary/Using filesort)。
  2. 覆蓋索引:SELECT 列 ⊆ 索引列 → Using index,避免回表。
  3. 避免 SELECT *:增加 I/O、網絡、緩存污染、無法用覆蓋索引。
  4. 條件下推:WHERE 條件盡量貼近存儲引擎層(索引條件下推 ICP)。
  5. 子查詢轉 JOIN:IN (SELECT ...) / EXISTS 在 5.6+ 多優化為 Semi-Join,但複雜子查詢建議顯式改寫。
  6. 分頁深度優化:大 offset 改用延遲關聯或游標分頁。
  7. 統計信息鮮度:ANALYZE TABLE 定期更新,誘導優化器選擇最優執行計劃。

結語

SELECT 是查詢的藝術,亦是優化的戰場。從「只取所需列」的覆蓋索引,到「深分頁」的延遲關聯重構;從 UNION ALL 的流式拼接,到 FOR UPDATE 的精準加鎖——每一個子句的選擇,都在為性能投票。願本文手冊助您在海量數據中,精準定位、極速歸航、穩健交付。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved