在 MySQL 中,所有資料欄位類型均可建立索引。對查詢條件中涉及的欄位加上索引,是提升 SELECT 查詢效能的最直接手段。各儲存引擎對每張表的最大索引數量及索引總長度有各自限制,但所有引擎至少支援每表 16 個索引、總長度 256 位元組,大多數引擎的上限更高。
MySQL 5.1 版本中,MyISAM 與 InnoDB 表的索引前綴長度可達 1,000 位元組。需注意前綴長度以位元組為單位,而 CREATE TABLE 中指定的長度為字元數;使用多位元組字元集(如 utf8)時須特別留意換算。此外,MyISAM 專有的 FULLTEXT 索引支援全文搜尋,僅限 CHAR、VARCHAR、TEXT 欄位,且不支援前綴索引;空間索引同樣僅 MyISAM 支援,採用 R-tree 結構。MEMORY 引擎預設使用 Hash 索引,亦可選擇 B-tree。
最適合建立索引的欄位是出現在 WHERE 條件、JOIN 連接條件中的欄位,而非 SELECT 選取清單中的欄位。
欄位值分布越唯一,索引效果越好。例如「身分證字號」極適合建唯一索引;而「性別」僅有 M/F 兩值,索引選擇率極低,建立索引幾無助益。
對長字串欄位(如 CHAR(200))建索引時,若前 10–20 字元已能區分大多數值,僅索引前綴可大幅節省空間、減少磁碟 I/O,並讓更多索引鍵值駐留在記憶體中,加快查詢。但前綴過短(如僅 1 字元)會導致基數極低,得不償失。
建立 (a,b,c) 複合索引等同於同時擁有 (a)、(a,b)、(a,b,c) 三個索引。查詢若能匹配最左側欄位集合,即可利用該索引;這與單欄位前綴索引截然不同。
索引並非「越多越好」。每個額外索引都佔用磁碟空間,並拖慢 INSERT/UPDATE/DELETE 寫入效能(需維護索引結構)。優化器生成執行計畫時也需遍歷更多索引,可能選錯最優索引。僅保留必要索引,若新增索引屬現有複合索引的最左前綴,則無需重複建立。
索引可服務於 =、<=>、IN、IS NULL、BETWEEN、>、< 等範圍條件,以及 LIKE 'prefix%' 固定前綴模糊查詢。若欄位僅用於 STRCMP() 等函式運算,建索引無意義。
| 特性 | B-tree 索引 | Hash 索引 |
|---|---|---|
| 支援運算子 | =、<=>、IN、IS NULL、>、<、>=、<=、BETWEEN、!=、<>、LIKE 'prefix%' | 僅 =、<=>(極快) |
| ORDER BY 加速 | 支援 | 不支援 |
| 範圍查詢 | 支援 | 不支援(無法估算行數) |
| 部分鍵值查詢 | 支援最左前綴 | 需完整鍵值 |
索引讓 MySQL 能快速定位到資料檔中間位置,避免全表掃描。對 1,000 筆資料的表,索引查詢至少快 100 倍;但若需存取大部分資料列,順序掃描反而更快(省去隨機 I/O)。大多數索引(主鍵、唯一、普通、全文)以 B-tree 存儲;空間索引用 R-tree;MEMORY 表另支援 Hash。