B樹和哈希索引的比較

前言

瞭解B樹和哈希數據結構有助於預測查詢在這些使用不一樣索引數據結構的存儲引擎上的執行狀況,特別是對於MEMORY存儲引擎,它是容許您選擇B樹或哈希做爲索引的存儲引擎。mysql

1. B樹指數特徵

B樹索引能夠在使用表達式中使用的對列的比較 =, >, >=, <, <=,或BETWEEN關鍵字。若是使用LIKE 或to LIKE且是一個不以通配符開頭的常量字符串,則索引也可用於比較 。算法

1.例如,如下SELECT語句將使用索引:sql

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'數據結構

2.如下SELECT語句不使用索引:函數

SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;

在第一個語句中,LIKE 值以通配符開頭。在第二個語句中,該LIKE值不是常量。優化

若是使用了像'%string%'且長度超過三個字符的字符串查詢,那麼MySQL將使用Turbo Boyer-Moore算法初始化這個模型,用這個模型來匹配速度會更快.spa

不跨越子句中的全部AND級別的 任何索引 WHERE不用於優化查詢。換句話說,爲了可以使用索引,必須在每一個AND組中使用索引的前綴 。code

3.如下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;

4.這些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不管如何都會使用索引,由於它能夠更快地找到在結果中返回幾行。

2. 哈希指數特徵

散列索引與剛纔討論的特徵有些不一樣:

  1. 它們僅用於使用=或<=>(文章結尾有此符號說明) 運算符的相等比較 (但速度很是快)。它們不用於比較運算符,例如 <找到一系列值。依賴於這種類型的單值查找的系統被稱爲「 鍵值存儲 」 ; 要將MySQL用於鍵值查找類,請儘量使用哈希索引。
  2. 優化器沒法使用哈希索引來加速 ORDER BY操做。(此類索引不能用於按順序搜索下一個條目。)
  3. MySQL沒法肯定兩個值之間大約有多少行(範圍優化器使用它來決定使用哪一個索引)。若是將 MyISAM或 InnoDB表更改成哈希索引 MEMORY表,則可能會影響某些查詢。
  4. 只有整個鍵可用於搜索行。(使用B樹索引,鍵的任何最左邊的前綴均可用於查找行。)

附錄

解釋=和<=>的區別:

相同點:  像常規的=運算符同樣,兩個值進行比較,結果是0(不等於)或1(相等),換句話說:’A'<=>’B'得0和’a'<=>’a‘得1,都是值的比較。不一樣點:  NULL的值是沒有任何意義的。因此=號運算符不能把NULL做爲有效的結果。因此:請使用<=>,'a' <=> NULL 得0 NULL<=> NULL 得出 1。和=運算符正相反,=號運算符規則是 'a'=NULL 結果是NULL 甚至NULL = NULL 結果也是NULL。順便說一句,mysql上幾乎全部的操做符和函數都是這樣工做的,由於和NULL比較基本上都沒有意義。用處當兩個操做數中可能含有NULL時,你須要一個一致的語句,此時就能夠用<=>.

相關文章
相關標籤/搜索