索引是資料庫提升查詢效能的核心機制。MySQL 支援多種索引類型,各有適用場景。本文系統整理索引分類、建立語法、優化原則及 EXPLAIN 實戰分析,助你構建高效能資料庫架構。
唯一且不允許 NULL 值,每張表僅能有一個主鍵。
-- 建表時指定
CREATE TABLE pk_test (
f1 INT NOT NULL,
PRIMARY KEY (f1)
);
-- 既有表新增
ALTER TABLE customer MODIFY id INT NOT NULL,
ADD PRIMARY KEY (id);
允許重複值,適用於頻繁查詢、排序或分組的欄位。
-- 建表時指定
CREATE TABLE tablename (
fieldname1 columntype,
fieldname2 columntype,
INDEX [indexname] (fieldname1[, fieldname2...])
);
-- 既有表新增
ALTER TABLE sales ADD INDEX idx_value (value);
值必須唯一,但允許 NULL(多個 NULL 視為不同值)。
CREATE TABLE ui_test (f1 INT, f2 INT, UNIQUE (f1));
ALTER TABLE ui_test ADD UNIQUE (f2);
專為大量文本(CHAR、VARCHAR、TEXT)設計,支援自然語言與布林模式搜尋。
CREATE TABLE ft2 (
f1 VARCHAR(255),
FULLTEXT (f1)
) ENGINE=MyISAM;
-- 自然語言模式
SELECT * FROM ft2 WHERE MATCH(f1) AGAINST('master');
-- 布林模式:+ 代表必含,- 代表排除
SELECT * FROM ft2
WHERE MATCH(f1) AGAINST('+master -pet' IN BOOLEAN MODE);
注意: MySQL 會忽略:(a) 出現於 50% 以上記錄的詞;(b) 長度 < 3 的詞;(c) 內建停用詞(如 the)。
對長字串欄位(VARCHAR、CHAR、BLOB、TEXT)僅索引前 N 個字元,節省空間並加快查詢。
ALTER TABLE customer ADD INDEX idx_surname_prefix (surname(10));
配合索引使用,常作為主鍵。
CREATE TABLE tablename (
id INT AUTO_INCREMENT PRIMARY KEY,
...
);
-- 重置計數器
ALTER TABLE tablename AUTO_INCREMENT = 50;
-- 取得最新插入 ID
SELECT LAST_INSERT_ID();
多欄主鍵中的自動遞增: 當主鍵為 (rank, id) 時,id 會在各 rank 群組內獨立遞增,無法手動重置計數器。
修改索引需先刪除再重建:
ALTER TABLE tablename DROP PRIMARY KEY;
ALTER TABLE tablename DROP INDEX indexname;
DROP INDEX indexname ON tablename;
SELECT * FROM customer WHERE surname > 'c'SELECT id FROM customer 僅讀取索引,無需回表SELECT * FROM customer ORDER BY surnamesurname LIKE 'ser%' 可用索引;%ser% 則不可WHERE、JOIN、ORDER BY 涉及的欄位建立索引INSERT/UPDATE/DELETE 開銷組合索引 (surname, initial, first_name) 實際建立了三個可用的索引層級:
(surname, initial, first_name)(surname, initial)(surname)失效範例: WHERE initial='x'、WHERE first_name='yvonne'、WHERE surname='clegg' AND first_name='yvonne'(跳過 initial)均無法使用組合索引。
EXPLAIN SELECT * FROM customer;
| 欄位 | 說明 |
|---|---|
| type | 連接類型,效能由好到差:system > const > eq_ref > ref > range > index > ALL |
| possible_keys | 可能使用的索引 |
| key | 實際使用的索引 |
| key_len | 索引長度,越短越好 |
| ref | 索引的哪一列被使用 |
| rows | 預估掃描行數 |
| Extra | 額外資訊(如 Using filesort、Using temporary 需優化) |
關鍵 Extra 值解讀:
Using filesort:需外部排序,優化索引或調整 ORDER BYUsing temporary:建立臨時表,常見於 ORDER BY 與 GROUP BY 欄位不一致Using index:覆蓋索引,極佳效能Using where:WHERE 子句過濾SHOW INDEX FROM tablename;
重點欄位:Cardinality(唯一值數量,越大區分度越高)、Sub_part(前綴長度)、Null(是否允許 NULL)。