索引是查詢加速器,也是寫入負擔。本文系統梳理索引定義、五大類型、創建刪除語法、使用原則、全文索引中文難點與最佳實踐。
案例:15 列表、10 個索引、500 萬行 → 大量導入時先刪索引、導數據、再建索引。
| 算法 | 查找次數 (N=100萬) | 特點 | |
|---|---|---|---|
| 全表掃描 | N/2 = 50萬 | 無索引 | |
| 二叉樹 | log₂N ≈ 20 | 平衡時最優,易退化鏈表 | |
| B+ 樹 (MySQL) | logₘN ≈ 3-4 | 多路平衡、葉子鏈表支援範圍查詢、磁盤友好 | |
| Hash | O(1) 理論 | 等值極快,不支援範圍/排序、衝突處理複雜 |
| 類型 | 關鍵字 | 特點 | 建表示例 |
|---|---|---|---|
| 普通索引 | INDEX / KEY | 僅加速查詢,允許重複、允許 NULL | ALTER TABLE t ADD INDEX idx_tel (tel); |
| 唯一索引 | UNIQUE INDEX | 值唯一,允許多個 NULL | ALTER TABLE t ADD UNIQUE INDEX uk_email (email); |
| 主鍵索引 | PRIMARY KEY | 唯一+非空,每表僅一個,聚簇索引 | ALTER TABLE t ADD PRIMARY KEY (id); |
| 全文索引 | FULLTEXT INDEX | 支援 MATCH...AGAINST 自然語言/布爾模式搜索 | ALTER TABLE t ADD FULLTEXT INDEX ft_intro (intro); |
| 組合索引 | INDEX (a,b,c) | 最左前綴原則,順序敏感 | ALTER TABLE t ADD INDEX idx_ab (a,b); |
CREATE TABLE t (
id INT PRIMARY KEY AUTO_INCREMENT,
email VARCHAR(30),
tel CHAR(11),
intro TEXT,
INDEX idx_tel (tel),
UNIQUE INDEX uk_email (email),
FULLTEXT INDEX ft_intro (intro)
) ENGINE=MyISAM CHARSET=utf8;
-- 普通/唯一/全文
ALTER TABLE t DROP INDEX idx_tel;
-- 主鍵(若為 AUTO_INCREMENT 需先移除屬性)
ALTER TABLE t MODIFY id INT; -- 去掉 AUTO_INCREMENT
ALTER TABLE t DROP PRIMARY KEY;
COUNT(DISTINCT col)/COUNT(*) > 0.1(JOIN 列)(a,b,c),查詢必須從 a 開始連續匹配WITH PARSER ngram),按 bigram 切分,勉強可用SHOW INDEX FROM t;
-- 關鍵列:Key_name, Column_name, Non_unique, Seq_in_index, Cardinality (區分度估值)

| 引擎 | 結構文件 | 數據文件 | 索引文件 |
|---|---|---|---|
| MyISAM | .frm | .MYD | .MYI |
| InnoDB | .frm | .ibd (含數據+索引) | 共享表空間 ibdata1 或 .ibd |

索引設計 = 業務查詢模式分析 + 區分度評估 + 寫入性能權衡。定期 ANALYZE TABLE 更新統計信息,配合 EXPLAIN 驗證執行計劃,是索引優化的常態化動作。