索引是對列值排序的數據結構,提供指向數據行的邏輯指針。作用等同圖書目錄:先查目錄定位頁碼,再翻頁獲取內容,避免全表掃描。
| 操作符 | B-Tree | Hash |
|---|---|---|
| =, <=>, IN, IS NULL, IS NOT NULL | ✓ | ✓ (極快) |
| >, <, >=, <=, BETWEEN, !=, <>, LIKE 'prefix%' | ✓ | ✗ |
| ORDER BY | ✓ | ✗ |
| 範圍優化器估算行數 | ✓ | ✗ |
結論:InnoDB 默認 B+Tree,通用性最強;Hash 僅適合純等值查詢且不需排序/範圍。
CREATE INDEX idx_name ON t_student(stu_name(4));
ALTER TABLE t_student ADD INDEX idx_name(stu_name(4));
CREATE TABLE t (..., INDEX idx_name (name(5)));
CREATE UNIQUE INDEX idx_uk ON t(col(length));
ALTER TABLE t ADD UNIQUE idx_uk (col(length));
CREATE INDEX idx_age_sex ON t_student(stu_age, stu_sex);
最左前綴原則:索引 (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 b=2、WHERE c=3、WHERE b=2 AND c=3 (未包含最左列 a)。
CREATE TABLE article (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
title VARCHAR(200),
content TEXT,
FULLTEXT (title, content)
) ENGINE=MyISAM;
-- 查詢
SELECT * FROM article WHERE MATCH(title, content) AGAINST('查詢字符串');
EXPLAIN SELECT * FROM t_student WHERE stu_age = 12;
-- key=idx_age_sex 表示用到索引
-- type=ref/range/eq_ref 非 ALL 即生效
LIKE 'abc%' 可用索引;LIKE '%abc%' 全表掃描。WHERE YEAR(date) < 2007 → 全表掃描。改為 WHERE date < '2007-01-01'。建表 t_student,加索引 idx_age_sex (age, sex),插入數據。
EXPLAIN SELECT * FROM t_student WHERE age=12 → key=idx_age_sex, type=ref (用到索引),結果按 sex、age 排序。
刪除索引後同樣查詢 → key=NULL, type=ALL (全表掃描),結果按 id 排序。