| 類型 | 關鍵字 | 特性 | 適用場景 |
|---|---|---|---|
| 普通索引 | INDEX / KEY | 無約束,允許 NULL,單列/組合 | 通用查詢加速 |
| 唯一索引 | UNIQUE INDEX | 值唯一,允許 NULL (多個 NULL) | 業務鍵:郵箱、手機號、身份證 |
| 主鍵索引 | PRIMARY KEY | 唯一、非 NULL、聚簇索引 (InnoDB) | 每表必有,主鍵查詢最快 |
| 組合索引 | INDEX(a,b,c) | 多列組合,**最左前綴原則** | 多條件聯合查詢 |
| 全文索引 | FULLTEXT | 全文搜尋,5.6+ InnoDB 支援 | 文章搜尋、日誌分析 |
| 空間索引 | SPATIAL | 地理空間數據 (GIS) | 地圖、位置服務 |
-- 1. 建表時創建
CREATE TABLE t (
id INT PRIMARY KEY,
name VARCHAR(20),
city VARCHAR(20),
age INT,
INDEX idx_name (name(10)), -- 前綴索引
UNIQUE INDEX uk_email (email),
INDEX idx_city_age (city, age) -- 組合索引
) ENGINE=InnoDB;
-- 2. 事後添加
ALTER TABLE t ADD INDEX idx_name (name(10));
ALTER TABLE t ADD UNIQUE INDEX uk_phone (phone);
ALTER TABLE t ADD INDEX idx_city_age (city, age);
-- 3. 刪除索引
DROP INDEX idx_name ON t;
ALTER TABLE t DROP INDEX uk_email;
索引 INDEX(a, b, c) 等價於擁有:
(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 AND b > 2 -- b 為範圍,c 用不到
WHERE a = 1 ORDER BY b -- 排序也用到
用不到索引的查詢:
WHERE b = 1 -- 缺最左列 a
WHERE b = 1 AND c = 2 -- 缺最左列 a
WHERE a = 1 AND c = 3 -- 中間斷層 (b 缺失),c 用不到
=, >, <, >=, <=, BETWEEN, IN, LIKE 'prefix%'ON t1.id = t2.id 兩側皆需索引SELECT a,b FROM t WHERE c=1 建 INDEX(c,a,b),只掃描索引不回表| 場景 | 示例 | 解決 |
|---|---|---|
| LIKE 以 % 開頭 | WHERE name LIKE '%abc' | 改 LIKE 'abc%' 或全文索引 |
| 列參與運算/函數 | WHERE YEAR(create_time) = 2024 | WHERE create_time >= '2024-01-01' AND create_time < '2025-01-01' |
| 隱式類型轉換 | WHERE phone = 13800000000 (phone 是 VARCHAR) | WHERE phone = '13800000000' |
| OR 條件未全索引 | WHERE a=1 OR b=2 (a 有索引,b 無) | 改 UNION 或給 b 加索引 |
| != / <> / NOT IN | WHERE status != 1 | 通常全表掃描,考慮覆蓋索引或改邏輯 |
| IS NULL / IS NOT NULL | WHERE deleted_at IS NULL | InnoDB 5.7+ 可用索引,但效果有限 |
INDEX(高區分度, 低區分度)VARCHAR(200) 實際存 20 字符 → INDEX(name(20)) 節省空間、提速EXPLAIN 出 Using index 為佳ANALYZE TABLE 更新統計信息 (或 innodb_stats_persistent=ON 自動持久化)EXPLAIN SELECT * FROM t WHERE name = 'abc';
-- 關鍵欄位:
-- type: ref/range/eq_ref (好) vs ALL (全表掃描,壞)
-- key: 實際用到的索引名
-- key_len: 索引長度 (判斷組合索引用了幾列)
-- rows: 預估掃描行數 (越小越好)
-- Extra: Using index (覆蓋索引), Using where, Using filesort (需優化)