對於 B-tree 和 hash 數據結構的理解可以有助於預測不一樣存儲引擎下使用不一樣索引的查詢性能的差別,尤爲是那些容許你選擇 B-tree 或者 hash 索引的內存存儲引擎。html
B-Tree 索引的特色
B-tree 索引能夠用於使用 =, >, >=, <, <= 或者 BETWEEN 運算符的列比較。若是 LIKE 的參數是一個沒有以通配符起始的常量字符串的話也可使用這種索引。好比,如下 SELECT 語句就使用索引:mysql
- 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 從句使用索引:sql
- ... 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 仍是會使用索引,由於它可以更快地找到這點記錄並將其返回。性能
Hash 索引的特色
Hash 索引有着與剛纔所討論特色的相比大相徑庭的特色:優化
- Hash 索引只可以用於使用 = 或者 <=> 運算符的相等比較(可是速度更快)。Hash 索引不可以用於諸如 < 等用於查找一個範圍值的比較運算符。依賴於這種單值查找的系統被稱爲 "鍵-值存儲";對於這種系統,儘量地使用 hash 索引。
- 優化器不可以使用 hash 索引來加速 ORDER BY 操做。這種類型的索引不可以用於按照順序查找下一個條目。
- MySql 沒法使用 hash 索引估計兩個值之間有多少行(這種狀況由範圍優化器來決定使用哪一個索引)。若是你將一張 MyISAM 或 InnoDB 錶轉換成一個 hash 索引的內存表時,一些查詢可能會受此影響。
- 查找某行記錄必須進行全鍵匹配。而 B-tree 索引,任何該鍵的左前綴均可用以查找記錄。
原文連接:http://dev.mysql.com/doc/refman/5.5/en/index-btree-hash.html。spa