最近在學后端,學到了這里做個記錄
一、為什么索引像書的目錄?
- 類比:500頁的技術書籍 vs 10頁的目錄
- 缺點:全表掃描就像逐頁翻找內容
- 優點:索引將查詢速度從O(n)提升到O(log n)
二、B+樹手繪課堂
1. 結構解剖(建議手繪圖包含以下元素)
+------------+| 非葉子節點 || [10, 20, 30] | ← 鍵值+指針+-----|--|-----+____/ \____/ \
+-----------+ +-----------+
| 葉子節點 | | 葉子節點 |
| [5,8,10] → | ←→ | [20,25,30] | ← 雙向鏈表
| 行數據指針 | | 行數據指針 |
+-----------+ +-----------+
- 用不同顏色標注:
- 紅色:節點分裂臨界點(每個節點最多存3個鍵值)
- 藍色:葉子節點的雙向指針
- 綠色:行數據實際存儲位置
2. 動態過程
- 插入過程:
插入28 → 定位到[20,25,30]節點 → 分裂為[20,25]和[28,30] 新增父節點指針
- 查詢路徑:
查找25 → 根節點→中間節點→葉子節點(3次磁盤IO)
三、InnoDB索引落地實現
1. 聚簇索引結構
[表空間文件示意圖]
+----------------------+
| 頁1: 索引節點 |
| 頁2: 葉子節點(行記錄)|
| 頁3: 溢出頁(TEXT字段)|
+----------------------+
2. 二級索引特殊機制
-- 創建示例
CREATE TABLE users (id INT PRIMARY KEY,username VARCHAR(20),INDEX idx_name (username) -- 存儲(username,id)
);-- 回表示例
EXPLAIN SELECT * FROM users WHERE username='Alice';
四、EXPLAIN執行計劃實戰
1. 關鍵字段解讀表
列名 | 索引健康度指標 | 優化提示 |
---|---|---|
type | ALL(全表) → range(范圍) → const(常量) | 爭取至少達到range級別 |
key_len | 使用的索引字節數 | utf8mb4字段需×4計算 |
Extra | Using index(覆蓋索引) | 出現Using filesort立即警報 |
2. 典型案例分析
-- 案例1:最左前綴原則
EXPLAIN SELECT * FROM orders
WHERE status='paid' AND create_time > '2023-01-01';
-- 可能的索引方案:
-- 方案A: INDEX(status, create_time) → type: range
-- 方案B: INDEX(create_time, status) → type: ref-- 案例2:索引合并
EXPLAIN SELECT * FROM products
WHERE category=1 OR price < 100;
-- 出現Using union(idx_category,idx_price)說明觸發了索引合并
五、性能優化-checklist
-
設計階段
- 整型主鍵比UUID減少30%存儲空間
- 聯合索引字段順序遵循ARC原則:
A(等值條件) → R(范圍條件) → C(排序字段)
-
調優階段
-- 查看索引使用情況 SELECT * FROM sys.schema_unused_indexes;-- 強制索引測試 SELECT * FROM table1 FORCE INDEX(idx_col1) WHERE...
-
緊急處理
# 快速定位索引問題 pt-index-usage /var/lib/mysql/mysql-slow.log
六、學習資源
- 推薦工具:
B+ Tree可視化工具