索引是排序後的資料結構(B+Tree),讓 MySQL 能以 O(log N) 定位行,而非全表掃描 O(N)。100 萬行表,有索引查詢可能只需 20 次比較,快 5 萬倍。
| 類型 | 定義 | 建立語法 | 限制 |
|---|---|---|---|
| 普通索引 | 無限制,允許 NULL/重複 | CREATE INDEX idx_name ON tbl(col(len))ALTER TABLE tbl ADD INDEX idx_name (col(len)) | — |
| 唯一索引 | 值唯一,允許 NULL | CREATE UNIQUE INDEX ...ALTER TABLE ... ADD UNIQUE ... | 組合索引時「列值組合」唯一 |
| 主鍵索引 | 特殊唯一索引,不允許 NULL | PRIMARY KEY (col) 建表時指定或 ALTER TABLE ... ADD PRIMARY KEY | 每表僅一個 |
| 全文索引 | FULLTEXT,專門文本搜尋 | FULLTEXT INDEX idx (col) | MyISAM 5.6+ InnoDB 支援 |
刪除:DROP INDEX idx_name ON tbl_name
表 myIndex(id PK, name, city, age, school_id),1 萬行,5 筆 name='erquan'。
name='erquan' → 中間結果集。city='鄭州'、age=25。(name(10), city, age)name='erquan' AND city='鄭州' AND age=25 的行,零掃描。name(10)) → 索引更小、更快、插入更新更輕。結論:組合索引 ≫ 多個單列索引。MySQL 單次查詢只能用到「一個」最佳索引,多個單列索引無法合併使用(Index Merge 例外但效率低)。
組合索引 (A, B, C) 等價於擁有三個虛擬索引:
(A, B, C)(A, B)(A)只有從最左列開始的連續前綴才能用到索引:
| WHERE 條件 | 是否用到索引 |
|---|---|
A=1 AND B=2 AND C=3 | ✅ |
A=1 AND B=2 | ✅ |
A=1 | ✅ |
B=2 AND C=3 | ❌(缺 A) |
C=3 | ❌ |
WHERE、JOIN ON、ORDER BY、GROUP BY 出現的欄位。=、<、>、<=、>=、BETWEEN、IN、LIKE 'prefix%'(不支援 %prefix 或 %prefix%)。INSERT/UPDATE/DELETE 需同步維護索引樹。EXPLAIN 確認 type=ref/range、key=預期索引、rows 遠小於總行數。SELECT *,只取需要欄位 → 可能觸發「覆蓋索引」Using index,零回表。ANALYZE TABLE 更新統計資訊,避免優化器誤判。col(10~20),平衡區分度與體積。ENUM。