了解 B 樹和雜湊資料結構有助於預測不同查詢在不同儲存引擎上的效能,這些儲存引擎在其索引中使用這些資料結構,特別是 MEMORY
儲存引擎,可讓您選擇 B 樹或雜湊索引。
B 樹索引可用於使用 =
、>
、>=
、<
、<=
或 BETWEEN
運算子的運算式中的資料行比較。如果 LIKE
的引數是一個不以萬用字元開頭的常數字串,則該索引也可用於 LIKE
比較。例如,下列 SELECT
語句使用索引
SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
在第一個語句中,只會考慮 'Patrick' <=
的資料列。在第二個語句中,只會考慮 key_col
< 'Patricl''Pat' <=
的資料列。key_col
< 'Pau'
下列 SELECT
語句不使用索引
SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;
在第一個語句中,LIKE
值以萬用字元開頭。在第二個語句中,LIKE
值不是常數。
如果您使用 ... LIKE '%
且 string
%'string
長度超過三個字元,MySQL 會使用 Turbo Boyer-Moore 演算法 初始化字串的模式,然後使用此模式更快地執行搜尋。
如果 col_name
有索引,使用
進行搜尋會使用索引。col_name
IS NULL
任何未涵蓋 WHERE
子句中所有 AND
層級的索引,都不會用於最佳化查詢。換句話說,為了能夠使用索引,索引的前綴必須在每個 AND
群組中使用。
以下 WHERE
子句會使用索引
... WHERE index_part1=1 AND index_part2=2 AND other_column=3
/* index = 1 OR index = 2 */
... WHERE index=1 OR A=10 AND index=2
/* optimized like "index_part1='hello'" */
... WHERE index_part1='hello' AND index_part3=5
/* Can use index on index1 but not on index2 or index3 */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
這些 WHERE
子句不會使用索引
/* index_part1 is not used */
... WHERE index_part2=1 AND index_part3=2
/* Index is not used in both parts of the WHERE clause */
... WHERE index=1 OR A=10
/* No index spans all rows */
... WHERE index_part1=1 OR index_part2=10
有時候,即使索引可用,MySQL 也不會使用索引。其中一種情況是,當最佳化器估計使用索引會讓 MySQL 存取資料表中非常大比例的列時。(在這種情況下,全表掃描可能更快,因為它需要的搜尋次數較少。)但是,如果這樣的查詢使用 LIMIT
只擷取部分列,MySQL 仍然會使用索引,因為它可以更快地找到結果中要傳回的少數列。
雜湊索引的特性與剛剛討論的那些略有不同
它們僅用於使用
=
或<=>
運算符的等式比較(但速度非常快)。它們不適用於尋找值範圍的比較運算符,例如<
。依賴這種單一值查找的系統稱為 “鍵值儲存”;要將 MySQL 用於此類應用,請盡可能使用雜湊索引。最佳化器無法使用雜湊索引來加速
ORDER BY
操作。(這種索引不能用於按順序搜尋下一個條目。)MySQL 無法大約判斷兩個值之間有多少列(範圍最佳化器會使用此資訊來決定要使用哪個索引)。如果您將
MyISAM
或InnoDB
資料表變更為雜湊索引的MEMORY
資料表,這可能會影響某些查詢。只能使用整個鍵來搜尋列。(對於 B 樹索引,可以使用鍵的任何最左側前綴來尋找列。)