首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> MySQL 資料庫 >> MySQL 綜合教學

MySQL WHERE 子句優化機制全解析:常數折疊、索引選擇、連接優化

     編輯:MySQL 綜合教學

MySQL WHERE 子句深度優化:從語法重寫到索引選擇的完整決策鏈

MySQL 查詢優化器對 WHERE 子句執行多層次優化。本文系統整理官方文檔優化規則:括號消除、常數傳播、死碼消除、索引統計採樣、常數表識別、連接順序枚舉、臨時表觸發條件、ICP/MRR 等進階特性,並給出典型高效查詢模式。

語法層面優化(解析器/優化器前端)

優化規則轉換示例
消除冗餘括號((a AND b) AND c) → (a AND b AND c)
常數傳播/摺疊(a < b AND b = c AND a = 5) → (b > 5 AND b = c AND a = 5)
消除常數條件(B>=5 AND B=5) OR (B=6 AND 5=5) → B=5 OR B=6
常數表達式單次計算索引條件中的常數表達式只算一次
無 WHERE 的 COUNT(*) 直接讀表統計MyISAM 瞬時返回;InnoDB 掃描主鍵
早期檢測不可能條件WHERE 1=0 直接返回空集
HAVING 無 GROUP BY 時併入 WHERE等價轉換簡化執行計劃

索引選擇與訪問路徑

  • 每張表獨立評估索引,選擇「過濾性最好」(掃描行數 < 30%)的索引
  • 若無合適索引 → 全表掃描
  • 覆蓋索引:查詢欄位全在索引中 → 僅讀索引樹,不回表(Using index)
  • 數值類型索引覆蓋查詢 → 僅走索引樹

常數表識別與優先讀取

以下情況視為「常數表」,優化器優先讀取並作為連接駕駛表:

  1. 空表或單行表
  2. 主鍵/唯一索引所有列參與等值比較,且列為 NOT NULL
-- 典型常數表
SELECT * FROM t WHERE primary_key = 1;
SELECT * FROM t1, t2 WHERE t1.pk = 1 AND t2.pk = t1.id;

連接順序優化

  • 枚舉所有連接排列,選擇成本最低者
  • 若 ORDER BY/GROUP BY 列來自同一表,該表優先作為駕駛表
  • SQL_SMALL_RESULT 提示使用內存臨時表

臨時表觸發條件

場景原因
ORDER BY 與 GROUP BY 列不一致需兩階段排序
ORDER BY/GROUP BY 包含非駕駛表列需收集所有行再排序
DISTINCT + ORDER BY轉為 GROUP BY 所有列

高效查詢模式速查

-- 1. 單表統計(極快)
SELECT COUNT(*) FROM tbl;
SELECT MIN(key), MAX(key) FROM tbl;
SELECT MAX(key2) FROM tbl WHERE key1 = const;

-- 2. 索引覆蓋 + LIMIT(極快)
SELECT * FROM tbl ORDER BY key1, key2 LIMIT 10;
SELECT * FROM tbl ORDER BY key1 DESC, key2 DESC LIMIT 10;

-- 3. 僅走索引樹(覆蓋索引)
SELECT key1, key2 FROM tbl WHERE key1 = val;
SELECT COUNT(*) FROM tbl WHERE key1 = v1 AND key2 = v2;
SELECT key2 FROM tbl GROUP BY key1;

-- 4. 索引順序掃描避免 filesort
SELECT * FROM tbl ORDER BY key1, key2;
SELECT * FROM tbl ORDER BY key1 DESC, key2 DESC;

HAVING 過濾時機

每行輸出前評估 HAVING,不匹配則跳過,不影響索引選擇。

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