索引是資料庫查詢效能的核心杠桿。MySQL 支援多種索引類型,各有適用場景與建立語法。本文系統梳理 4 大核心索引類型、建立三種方式、組合索引「最左前綴」原理與實戰選擇策略,助你精準建立高效索引。
僅加速查詢,允許重複值與 NULL 值。
-- 三種建立方式
-- 方式一:獨立建立
CREATE INDEX idx_username ON mytable(username(10));
-- 方式二:ALTER TABLE
ALTER TABLE mytable ADD INDEX idx_username (username(10));
-- 方式三:建表時指定
CREATE TABLE mytable (
id INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX idx_username (username(10))
);
-- 刪除
DROP INDEX idx_username ON mytable;
長度策略:CHAR/VARCHAR 可指定前綴長度(如 username(10)),BLOB/TEXT 必須 指定長度。適當前綴可大幅縮小索引體積、提升插入速度。
CREATE UNIQUE INDEX uk_email ON users(email(50));
ALTER TABLE users ADD UNIQUE uk_email (email(50));
CREATE TABLE users (... UNIQUE uk_email (email(50)) );
組合唯一索引時,列值組合必須唯一。NULL 值在唯一索引中視為「不相等」,可存在多個 NULL。
-- 建表時指定(推薦)
CREATE TABLE mytable (
id INT NOT NULL AUTO_INCREMENT,
username VARCHAR(16) NOT NULL,
PRIMARY KEY (id)
);
-- 事後新增
ALTER TABLE mytable ADD PRIMARY KEY (id);
鐵律:一個表僅能有一個主鍵。InnoDB 若無顯式主鍵,會隱式建立 6 字節行 ID,強烈建議顯式定義業務主鍵或自增代理鍵。
-- 建立 name(10), city, age 組合索引
ALTER TABLE mytable ADD INDEX idx_name_city_age (name(10), city, age);
上述索引等價於隱式建立三組索引:
(name, city, age)
(name, city)
(name)
SELECT * FROM mytable WHERE name = 'admin' AND city = '台北';
SELECT * FROM mytable WHERE name = 'admin';
SELECT * FROM mytable WHERE age = 20 AND city = '台北'; -- 缺少最左列 name
SELECT * FROM mytable WHERE city = '台北'; -- 缺少最左列 name
LIKE 'prefix%' 可用索引,LIKE '%suffix' 無法用索引WHERE、JOIN ON、ORDER BY、GROUP BY 的欄位
EXPLAIN SELECT * FROM mytable WHERE name = 'admin' AND city = '台北';
-- 關鍵欄位:
-- type: ref/range/eq_ref 表示用到索引
-- key: 實際使用的索引名
-- key_len: 使用的索引長度(驗證組合索引用了幾列)
-- rows: 預估掃描行數(越小越好)
索引設計是「測試-觀測-調整」的迭代過程。善用 EXPLAIN、SHOW INDEX、sys.schema_index_statistics 等工具,持續優化索引策略。