無索引表 = 無序堆,查詢需全表掃描。索引 = 有序數據結構(B+Tree),提供:
ORDER BY/GROUP BY 避免排序| 類型 | 結構 | 支援操作 | 典型場景 |
|---|---|---|---|
| B+Tree(預設) | 平衡樹 | =、>、<、>=、<=、BETWEEN、LIKE 'prefix%'、ORDER BY、GROUP BY | 通用、範圍查詢、排序 |
| Hash | 哈希表 | =、IN | MEMORY 引擎、精確查找、無範圍/排序需求 |
| Fulltext | 倒排索引 | MATCH ... AGAINST | 全文搜索(5.6+ InnoDB 支援) |
| Spatial (R-Tree) | R 樹 | MBRContains、ST_Distance | GIS 地理空間 |
選擇性 = COUNT(DISTINCT col) / COUNT(*),越接近 1 越好(唯一鍵=1)INDEX (a,b,c) 支援 a/a,b/a,b,c,不支援 b/c/b,cWHERE a=1 AND b>2 AND c=3 → INDEX (a,c,b) 或 (a,b)(範圍列後的列失效)SELECT a,b FROM t WHERE c=1 → INDEX (c,a,b),Using index 避免回表PRIMARY KEY (id) + INDEX (id) 重複;INDEX (a,b) 已覆蓋 INDEX (a)| 模式 | 原因 | 修正 |
|---|---|---|
WHERE col + 1 = 5 | 列參與運算/函數 | WHERE col = 4 |
WHERE SUBSTR(col,1,3)='abc' | 函數破壞索引順序 | WHERE col LIKE 'abc%' |
WHERE col LIKE '%abc%' | 前導通配符無法利用 B+Tree 有序性 | 全文索引/外部搜索引擎 |
WHERE varchar_col = 123 | 隱式類型轉換(字串轉數字) | WHERE varchar_col = '123' |
WHERE a=1 OR b=2 | OR 通常導致全表掃描 | UNION ALL 分拆/優化器 5.7+ Index Merge |
IS NULL / IS NOT NULL | 5.6+ 可用索引,舊版不可 | 升級/改用預設值+等值查詢 |
ANALYZE TABLE 更新統計,否則優化器誤判
-- 1. 查看表索引
SHOW INDEX FROM tbl;
-- 2. 分析查詢計畫
EXPLAIN SELECT ...;
-- 關注:type(ALL/index/range/ref/eq_ref/const)、key、rows、Extra(Using index/Using where/Using temporary/Using filesort)
-- 3. 發現缺失索引
-- 慢查詢日誌 + pt-query-digest → 高頻慢 SQL → EXPLAIN 驗證 → 加索引
-- 4. 發現冗餘/未用索引
-- sys.schema_unused_indexes / sys.schema_redundant_indexes (5.7+)
-- 或長期監控 INNODB_INDEX_USAGE / USER_INDEX_USAGE
索引是有序數據結構換取查詢速度的空間/寫入成本。核心功課:**理解 B+Tree 原理、掌握最左前綴、識別失效模式、定期審計索引使用情況**。沒有銀彈,只有基於負載特徵的持續調優。