索引是用來快速尋找具有特定資料行值的資料列。如果沒有索引,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 節,「避免全表格掃描」。