B+樹勝出的關鍵特性:
矮胖樹結構:3-4層高度即可存儲2000萬條記錄(假設每頁存1000條)
葉子鏈表:所有數據存儲在葉子節點,并通過雙向鏈表連接
非葉導航:非葉子節點僅存儲鍵值,不保存數據,提升節點容量
2. 實戰案例:索引如何加速查詢?
2.1 案例1:超市儲物柜系統
2.1.1 場景描述
表結構:2000個儲物柜,字段包括柜號(主鍵)、手機號、使用時間等。
高頻查詢:用戶通過手機號查找柜號(SELECT * FROM lockers WHERE phone='13812345678')。
2.1.2 無索引的代價
全表掃描2000條數據,平均需訪問1000次磁盤頁(假設每頁20條記錄)。
2.1.3 創建索引后的優化
CREATE INDEX idx_phone ON lockers(phone); ?
查詢過程:
從根節點定位手機號138所在的頁。
中間層定位到1381234的分支。
葉子層找到13812345678對應的柜號。
根據柜號直接訪問目標數據頁。
磁盤I/O次數:3次(樹高3層) vs 全表掃描的100次。
2.2 案例2:醫院叫號系統的聯合索引
2.2.1 聯合索引設計
ALTER TABLE patients ADD INDEX idx_dept_status_time(department, status, register_time); ?
最左前綴原則:
有效查詢:WHERE department='心血管科' AND status='待就診'(使用前兩列)。
無效查詢:WHERE status='待就診'(跳過第一列,觸發全表掃描)。
2.2.2 索引覆蓋優化
SELECT id, department FROM patients WHERE department='心血管科'; ?
若索引包含所有查詢字段,直接返回索引數據,無需回表。
3. 索引設計與避坑指南
3.1 設計原則
三星索引標準:
一星:WHERE條件匹配索引列。
二星:ORDER BY/GROUP BY使用索引排序。
三星:SELECT字段全部在索引中。
選擇性原則:
優先為區分度高的列建索引(如性別字段區分度低,手機號區分度高)。
計算公式:選擇性 = 不同值數量 / 總行數。
3.2 常見陷阱
1. 隱式類型轉換
SELECT * FROM users WHERE phone = 13812345678; -- phone為varchar類型 ?
導致索引失效,需強制轉換:WHERE phone = '13812345678'。
2. 函數操作破壞索引
SELECT * FROM orders WHERE DATE_FORMAT(create_time,'%Y-%m')='2025-03'; ?
改寫為范圍查詢:WHERE create_time >= '2025-03-01' AND create_time < '2025-04-01'。
4. 進階:索引的底層維護
4.1 頁分裂與合并
插入觸發頁分裂:當葉子頁已滿時,分裂為兩個頁,父節點新增指針。
刪除觸發頁合并:當頁利用率低于閾值時,合并相鄰頁并更新指針。
4.2 索引統計信息
MySQL定期更新 INDEX_STATISTICS,優化器根據數據分布選擇索引。
手動更新命令:ANALYZE TABLE patients;