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

MySQL 索引優化實戰指南(重構版):架構、類型、最左前綴、失效場景、工具選型與避坑清單

     編輯:MySQL 綜合教學

MySQL 索引優化系統性實戰指南(深度重構版)

一、MySQL 三層邏輯架構

  1. 連接層:連接池、認證、執行緒
  2. 服務層:解析、優化、快取、視圖、函數
  3. 儲存引擎層:InnoDB、MyISAM 等,索引實際存放處

二、索引類型全景圖

分類類型關鍵特性
資料結構B+ 樹範圍、排序、最左前綴,通用首選
Hash精確匹配 O(1),無範圍/排序,Memory 專用
Fulltext全文搜尋,5.6+ InnoDB 支援
R-TreeGIS 空間資料,SPATIAL 索引
物理存儲聚簇索引主鍵即資料,InnoDB 預設
非聚簇索引次級索引,葉子存主鍵,需回表
邏輯功能主鍵索引唯一、非空、單表一個
普通/單列基礎索引
複合/多列遵循最左前綴
唯一索引值唯一,允許多 NULL
空間索引GIS 類型,MyISAM 專用

三、建立索引語法

CREATE TABLE t(
  a INT, b VARCHAR(50),
  INDEX idx_a (a),
  UNIQUE uk_b (b),
  INDEX idx_a_b (a, b)  -- 複合索引順序關鍵
);

ALTER TABLE t ADD INDEX idx_a (a);
CREATE INDEX idx_a ON t(a);

四、建立索引鐵律

  1. 低基數(性別/狀態)不建
  2. 高頻更新欄位不建
  3. 無 Bitmap 索引
  4. Text/Blob 全文 → Elasticsearch/Sphinx
  5. 高頻 WHERE/ORDER BY/GROUP BY/DISTINCT 必建
  6. 索引不過多:每索引 = 一棵 B+ 樹維護成本
  7. 優先複合,少單列
  8. 字串建前綴:INDEX idx_name (name(18))
  9. 複合索引序:過濾性最高/最左前綴優先

五、最左前綴匹配原則(必背)

從左向右匹配,**遇到範圍查詢 (>、<、>=、<=、LIKE %...、BETWEEN) 即停止**。

-- 索引 (a,b,c,d)
a=1 AND b=2 AND c>3 AND d=4  -- 用到 a,b,c;d 失效

-- 優化:索引 (a,b,d,c) → 全用到
-- = 和 IN 可亂序,優化器自動重排

六、可用索引的運算符

  • <、<=、=、>、>=、BETWEEN
  • LIKE 'prefix%'(非萬用字元開頭)
  • col IS NULL(已建索引)
  • 多條件:Index Merge (union/intersection/sort-union)

七、7 大索引失效場景

  1. 掃描行數 > 30% → 全表掃描
  2. 複合索引首列用範圍查詢
  3. Memory 表 Hash 索引做範圍/排序
  4. WHERE key1=? ORDER BY key2 → 僅用一索引
  5. 關聯欄位型別/長度不一致 → 隱式轉換
  6. 索引列用函數/運算:func(col)、col+1 ❌
  7. 字元集/排序規則不一致導致隱式轉換

八、索引三大成本(副作用)

  1. 維護成本:增刷改同步 B+ 樹
  2. 訪問成本:遍歷索引樹
  3. 空間成本:磁碟+記憶體佔用

九、工具選型建議

工具適用場景注意事項
pt-index-usage低峰期分析特定表 slow log需 long_query_time=0,大檔案慢
EXPLAIN + SHOW INDEX單條 SQL 即時分析結合業務知識人工判斷
sys.schema_unused_indexesMySQL 5.7+ 系統視圖基於 performance_schema,零侵入
information_schema.INDEX_STATISTICS啟用 userstat 時可用風險較高,生產慎開

十、避坑速查清單

  • ✅ 複合索引順序 = WHERE 條件順序 = 最左前綴
  • ✅ 範圍列放複合索引最後
  • ✅ 關聯查詢雙方欄位型別、長度、字元集**完全一致**
  • ✅ 避免 WHERE col = DATE_FORMAT(...) 等函數包裹索引列
  • ✅ 定期 ANALYZE TABLE 更新統計資訊
  • ✅ 監控 Handler_read_rnd_next(全表掃描計數)
  • ❌ 不要在每個欄位都建單列索引
  • ❌ 不要用 SELECT * 導致回表
  • ❌ 不要用 OFFSET 1000000 LIMIT 10 深分頁(改用游標/延遲關聯)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved