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

MySQL 索引分類、選擇原則與優化實戰:從 B+Tree 到最左前綴

     編輯:MySQL 資料庫相關知識

索引是 MySQL 查詢性能的核心。本文系統梳理索引存儲結構、分類體系、創建語法、選擇策略、最左前綴原理、常見誤區,幫助開發者建立科學的索引設計思維。

一、索引底層存儲結構

  • InnoDB:B+Tree 聚簇索引(主鍵即數據),二級索引葉子節點存主鍵值
  • MyISAM:B+Tree 非聚簇索引,葉子節點存數據文件指針
  • Memory:可選 Hash(等值查詢 O(1))或 BTree(範圍查詢)

二、索引分類與創建語法

類型特點創建語法
普通索引無唯一性限制,最基礎CREATE INDEX idx_name ON tbl(col);
ALTER TABLE tbl ADD INDEX idx_name (col);
唯一索引值不可重複,允許 NULLCREATE UNIQUE INDEX idx_name ON tbl(col);
主鍵特殊唯一索引,非空、唯一、一表僅一個PRIMARY KEY (col) 建表時或 ALTER TABLE tbl ADD PRIMARY KEY (col);
全文索引5.6+ InnoDB 支持,專用於 MATCH...AGAINSTFULLTEXT INDEX idx_name (col);
單列索引單字段同上
多列/聯合索引多字段組合,遵循最左前綴CREATE INDEX idx_a_b_c ON tbl(a,b,c);

三、最左前綴原理(聯合索引核心)

對聯合索引 (a, b, c):

WHERE 條件是否用到索引用到的索引列
a=1 AND b=2 AND c=3✅a, b, c
a=1 AND b=2✅a, b
a=1✅a
b=2❌—(非最左列)
a=1 AND c=3⚠️a(c 斷層無法用)
ORDER BY a, b✅a, b(避免 filesort)

本質:B+Tree 索引按 (a, b, c) 排序,只能從最左列開始連續匹配。

四、索引列選擇黃金法則

  1. 出現在 WHERE/JOIN/ORDER BY/GROUP BY 的高頻列優先
  2. 區分度高(基數大)的列優先:COUNT(DISTINCT col)/COUNT(*) > 0.1 才值得建索引
  3. 短索引:字符串列指定前綴長度 INDEX idx_name (name(10)),節省空間、提升速度
  4. 利用最左前綴:聯合索引將高區分度列放左邊
  5. 拒絕過度索引:每個索引增加寫入開銷(INSERT/UPDATE/DELETE 需維護 B+Tree),僅保留必要索引

五、MySQL 使用索引的操作符條件

僅以下操作符可能觸發索引:

<, <=, =, >, >=, BETWEEN, IN, LIKE 'prefix%'

不走索引:LIKE '%suffix'、LIKE '%mid%'、函數包裹列 WHERE UPPER(col)='A'、隱式類型轉換 WHERE varchar_col = 123、OR 兩側索引不一致。

六、索引優化實戰檢查清單

場景問題優化動作
查詢慢EXPLAIN 顯示 type=ALL添加 WHERE/JOIN 列索引
索引未命中函數/運算在列上改寫 SQL,移至常量側
聯表慢JOIN 列無索引/類型不一致駆動表小、被驅動表 JOIN 列建索引、類型統一
排序慢Using filesort建立符合 ORDER BY 順序的聯合索引
分頁深LIMIT 100000, 10延遲關聯/游標分頁/覆蓋索引

七、覆蓋索引與索引下推(ICP)

  • 覆蓋索引:查詢列全包含在索引中,EXPLAIN 顯示 Using index,無需回表
  • ICP (5.6+):存儲引擎層過濾 WHERE 條件,減少回表次數,Using index condition

八、避坑指南

  1. 主鍵盡量用自增 BIGINT,避免 UUID 導致頁分裂
  2. 外鍵列必須建索引(InnoDB 不自動創建)
  3. 定期 ANALYZE TABLE 更新統計信息,防優化器誤判
  4. 大表加索引用 pt-online-schema-change 避免鎖表

索引設計 = 業務查詢模式分析 + 數據分布統計 + 寫入性能權衡。無銀彈,只有持續觀測與調優。

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