索引是資料庫提升查詢效能的關鍵結構,類比書籍目錄:無需掃描全書即可定位內容。在 MySQL 中,索引屬於儲存引擎層實作,不同引擎(InnoDB、MyISAM)的索引結構略有差異。
| 分類 | 類型 | 建立語法 | 特點 |
|---|---|---|---|
| 按功能 | 主鍵索引 | PRIMARY KEY (id) |
唯一、非空、叢集索引(InnoDB) |
| 唯一索引 | UNIQUE INDEX uk_email (email) |
值唯一、允許一個 NULL | |
| 按結構 | 單欄索引 | INDEX idx_name (name) |
單一欄位、最常用 |
| 複合索引 | INDEX idx_name_age (name, age) |
多欄位、遵循最左前綴原則 | |
| 全文索引 | FULLTEXT INDEX ft_content (content) |
支援自然語言/布林模式搜尋 | |
| 按儲存 | 叢集索引 | InnoDB 主鍵自動建立 | 資料與索引共存、葉節點即資料頁 |
| 非叢集索引 | 其餘所有索引 | 葉節點存主鍵值、需回表查資料 |
INDEX idx_a_b_c (a, b, c)
等價於建立:(a)、(a,b)、(a,b,c) 三個索引。
| 查詢條件 | 是否用到索引 | 說明 |
|---|---|---|
WHERE a=1 | ✅ 是 | 最左列匹配 |
WHERE a=1 AND b=2 | ✅ 是 | 最左兩列匹配 |
WHERE b=2 | ❌ 否 | 非最左列,無法使用 |
WHERE a=1 AND c=3 | 部分 | 僅用到 a,c 無法用到 |
WHERE a=1 ORDER BY b | ✅ 是 | 排序也能用到索引順序 |
WHERE YEAR(create_time)=2023 → 改用 WHERE create_time >= '2023-01-01' AND create_time < '2024-01-01'WHERE varchar_col = 123 → 字串比數字會觸發全表掃描WHERE name LIKE '%abc' → 無法使用索引WHERE a=1 OR b=2 → 若 b 無索引則全表掃描INDEX(a,b) 優於 INDEX(a) + INDEX(b)ANALYZE TABLE 更新統計資訊,OPTIMIZE TABLE 整理碎片-- 原查詢:慢
SELECT * FROM orders WHERE user_id=1001 AND status=1 ORDER BY create_time DESC LIMIT 10;
-- 優化:建立複合索引
ALTER TABLE orders ADD INDEX idx_user_status_time (user_id, status, create_time);
-- 覆蓋索引進階(若只查特定欄位)
ALTER TABLE orders ADD INDEX idx_cover (user_id, status, create_time, order_no, amount);
掌握索引原理、善用 EXPLAIN 分析、避開失效陷阱,是 MySQL 效能調優的核心功力。