索引用於快速尋找具有特定欄位值的列。若沒有索引,MySQL 必須從第一列開始,然後讀取整個資料表才能找到相關的列。資料表越大,成本就越高。如果資料表有所需欄位的索引,MySQL 可以快速判斷在資料檔中間要搜尋的位置,而無需查看所有資料。這比依序讀取每一列快得多。
大多數 MySQL 索引 (PRIMARY KEY
、UNIQUE
、INDEX
和 FULLTEXT
) 都儲存在 B 樹中。例外情況:空間資料類型上的索引使用 R 樹;MEMORY
資料表也支援 雜湊索引;InnoDB
使用倒置列表作為 FULLTEXT
索引。
一般來說,索引的使用方式如下所述。雜湊索引的特定特性 (在 MEMORY
資料表中使用) 在第 10.3.9 節「B 樹和雜湊索引的比較」中有說明。
MySQL 使用索引進行下列操作
快速尋找符合
WHERE
子句的列。排除考慮的列。如果有多個索引可供選擇,MySQL 通常會使用尋找最少列的索引 (最具選擇性的索引)。
如果資料表具有多欄索引,最佳化工具可以使用索引的任何最左側前綴來尋找列。例如,如果您在
(col1, col2, col3)
上建立三欄索引,您可以在(col1)
、(col1, col2)
和(col1, col2, col3)
上建立索引搜尋功能。如需更多資訊,請參閱第 10.3.6 節「多欄索引」。在執行聯結時,從其他資料表擷取列。如果 MySQL 欄位的宣告類型和大小相同,則可以更有效率地使用欄位上的索引。在這種情況下,如果宣告的大小相同,
VARCHAR
和CHAR
會被視為相同。例如,VARCHAR(10)
和CHAR(10)
的大小相同,但VARCHAR(10)
和CHAR(15)
的大小不同。對於非二進位字串欄位之間的比較,這兩個欄位應該使用相同的字元集。例如,比較
utf8mb4
欄位和latin1
欄位會排除使用索引。比較不同類型的資料欄(例如,將字串欄位與時間或數值欄位進行比較)可能會因為數值無法在未經轉換的情況下直接比較,而導致無法使用索引。例如,數值欄位中的值
1
可能會與字串欄位中的許多值相等,例如'1'
、' 1'
、'00001'
或'01.e1'
。這會排除對字串欄位使用任何索引的可能性。尋找特定索引欄位
key_col
的MIN()
或MAX()
值。這會由預處理器最佳化,該預處理器會檢查您是否在索引中key_col
之前的所有索引鍵部分使用了WHERE
。在這種情況下,MySQL 會為每個key_part_N
=constant
MIN()
或MAX()
運算式執行單一索引鍵查找,並將其替換為常數。如果所有運算式都被替換為常數,則查詢會立即返回。例如SELECT MIN(key_part2),MAX(key_part2) FROM tbl_name WHERE key_part1=10;
如果排序或分組是依據可用索引的最左側前綴來完成,則對表格進行排序或分組(例如,
ORDER BY
)。如果所有索引鍵部分都後接key_part1
,key_part2
DESC
,則會以反向順序讀取索引鍵。(或者,如果索引是降序索引,則會以正向順序讀取索引鍵。)請參閱 第 10.2.1.16 節,「ORDER BY 最佳化」、第 10.2.1.17 節,「GROUP BY 最佳化」 和 第 10.3.13 節,「降序索引」。在某些情況下,可以最佳化查詢以檢索值,而無需查詢資料列。(提供查詢所需所有結果的索引稱為涵蓋索引。)如果查詢僅使用表格中包含在某些索引中的欄位,則可以從索引樹中檢索選定的值以提高速度。
SELECT key_part3 FROM tbl_name WHERE key_part1=1
對於小型表格或報表查詢處理大多數或所有列的大型表格,索引的重要性較低。當查詢需要存取大多數列時,循序讀取比透過索引工作更快。循序讀取可最大程度地減少磁碟搜尋,即使查詢並非需要所有列。請參閱 第 10.2.1.23 節,「避免完整表格掃描」以取得詳細資訊。