索引是查詢加速的核心手段,但「有索引不一定快,無索引一定慢」。優化金字塔:Schema 設計 → 索引策略 → SQL 改寫 → 配置調優 → 架構擴展 → 硬件升級。
| 類型 | 關鍵字 | 特點 | 適用場景 |
|---|---|---|---|
| 主鍵索引 | PRIMARY KEY | 唯一、非空、聚簇索引 (InnoDB 數據與索引存一起) | 每張表必須有,業務主鍵或自增 ID |
| 唯一索引 | UNIQUE | 值唯一,允許多個 NULL | 業務唯一鍵 (手機、郵箱、身份證) |
| 普通索引 | INDEX / KEY | 無唯一限制,允許重複和 NULL | 高頻 WHERE/JOIN/ORDER BY 列 |
| 全文索引 | FULLTEXT | 分詞搜索,MyISAM 早期支持,InnoDB 5.6+ 支持,中文需分詞器 | 文章搜索、日志分析 (配合 Sphinx/Elasticsearch 更強) |
-- 建表時
CREATE TABLE t (
id INT PRIMARY KEY,
name VARCHAR(32),
email VARCHAR(64) UNIQUE,
content TEXT,
INDEX idx_name (name),
FULLTEXT ft_content (content)
) ENGINE=InnoDB;
-- 事後添加
ALTER TABLE t ADD INDEX idx_name (name);
ALTER TABLE t ADD UNIQUE uk_email (email);
ALTER TABLE t ADD FULLTEXT ft_content (content);
CREATE INDEX idx_name ON t(name);
CREATE UNIQUE INDEX uk_email ON t(email);
-- 前綴索引 (大字段必用)
CREATE INDEX idx_email_prefix ON t(email(10)); -- 索引前 10 字符
-- BLOB/TEXT 必須指定前綴長度
| 引擎 | 支持類型 | 默認 |
|---|---|---|
| InnoDB | BTREE | BTREE |
| MyISAM | BTREE | BTREE |
| Memory | HASH, BTREE | HASH |
BTREE:範圍查詢、排序、分組、最左前綴匹配全支持。**通用首選**。
HASH:僅支持 =、IN、<=> 精確查找,O(1) 極快,但不支持範圍/排序。適合 Memory 引擎的精確查找表。
複合索引 INDEX idx_a_b_c (a, b, c) 等價於建立三棵 B+ 樹:(a), (a,b), (a,b,c)。
WHERE a=1、WHERE a=1 AND b=2、WHERE a=1 AND b=2 AND c=3、WHERE a=1 ORDER BY b、WHERE a=1 AND b=2 ORDER BY cWHERE b=2 (缺最左列 a)、WHERE a=1 AND c=3 (中間斷層 b)、WHERE a=1 ORDER BY c (跳過 b 導致排序無序)WHERE a=1 AND b>2 AND c=3 → c 用不上索引 (b 是範圍查詢)WHERE name LIKE '%abc' → 全表掃描。LIKE 'abc%' 可用索引WHERE phone = 13800000000 → 列轉數字,索引失效。**永遠加引號!**WHERE a=1 OR b=2,若 a、b 無聯合索引 → 全掃。**改用 UNION ALL**WHERE DATE(create_time) = '2024-01-01' → 改為 WHERE create_time >= '2024-01-01' AND create_time < '2024-01-02'ANALYZE TABLE 更新統計INDEX idx_a_b_c (a, b, c) 滿足 SELECT a,b,c FROM t WHERE a=1SET innodb_stats_persistent=ON + 定期 ANALYZE TABLE
-- 1. 查看索引使用情況
SHOW STATUS LIKE 'Handler_read%';
-- Handler_read_key: 索引讀取次數 (越高越好)
-- Handler_read_rnd_next: 全表掃描次數 (越低越好)
-- 2. EXPLAIN 實戰
EXPLAIN SELECT * FROM t WHERE a=1 AND b=2;
-- 關鍵列:type (ref/range/ALL), key (實際用索引), key_len, rows (預估掃描行), Extra (Using index/Using where/Using filesort)
-- 3. 索引統計信息
SHOW INDEX FROM t;
-- Cardinality: 基數 (去重行數),越接近總行數選擇性越高
OPTIMIZE TABLE 或 ALTER TABLE ... ENGINE=InnoDB 重建 (在線 DDL 工具首選)sys.schema_unused_indexes (5.7+ sys schema) 定期清理無用索引,減少寫入開銷idx_ 普通、uk_ 唯一、fk_ 外鍵、ft_ 全文,便於識別管理