首發:www.leroyling.com/archives/my…mysql
生活中,若是你想要快速的在一本書中找到某個你感興趣的內容,通常來說是會先看書的「索引」部分,也就是書的目錄,找到對應的頁碼以後,再翻去看你感興趣的具體內容。sql
在MySQL中,存儲引擎也用的相似的方法使用索引,即如今索引中找到對應的值,而後根據匹配到的索引的記錄找到對應的數據行。索引能夠包含一個或多個列的值,若是索引含有多個列,那麼如何放置列的順序也是至關重要的,由於在MySQL中只能高效的使用索引的最左前綴列。因此在MySQL中建立一個包含兩個列的索引,和單首創建兩個各自只包含一個列的索引效果也會大不同。函數
通常來講,當咱們說到索引的時候,若是沒有特別的指明類型,那麼多半來講,默認說的就是B-Tree索引了(不一樣的存儲引擎中,可能使用了不一樣的存儲結構,如InnoDB引擎中使用的是B+Tree)。性能
使用B-Tree索引,意味着所存儲的值是按照順序存儲的。使用索引之因此能加快訪問數據的速度,是由於存儲引擎不在須要對數據進行全表掃描了,而是從索引的根節點開始搜索,經過比較節點頁的值和實際要查找的值,從而找到合適的指針進入下層的子節點進行查找。 以一張簡單的表爲例:優化
CREATE TABLE ORDER(
order_id varchar(32) not null,
product_code varchar(20) not null,
order_time datetime not null,
order_price decimal(10,2) not null default 0,
address varchar(100) not null
key(order_id,product_code,order_time)
)
複製代碼
對於上面表中的每一條數據,索引中都包含了 order_id, product_code, order_time這三列的值。對於多個列的值進行排序的時候,排序規則是根據create語句中定義索引時使用的列順序來進行的,以上表爲例,即排序的順序爲order_id, product_code, order_time。ui
select * from order where order_id ='o001' and product_code='p001' and order_time='2019-12-05';
複製代碼
select * from order where order_id='o001';
select * from order where order_id='o001' and product_code='p001'
複製代碼
select * from order where order_id like 'o001%';
select * from order where order_id ='o0001' and product_code like 'p001%';
複製代碼
select * from order where order_id >='o001';
select * from order where order_id = 'o001' and product_code >'p001';
select * from order where order_id = 'o001' and product_code ='p001' and order_time >'2019-12-01';
複製代碼
只訪問索引的查詢搜索引擎
即查詢只須要訪問索引而無需訪問數據行,此時這種查詢進化爲一種名爲「覆蓋索引」查詢。所謂的「覆蓋索引」指的是若是一個索引包含(或者說覆蓋)全部須要查詢返回的字段的值,那麼這個索引就稱之爲「覆蓋索引」。此時查詢結果可使用索引來直接獲取列的數據,再也不須要回表讀取數據行。spa
哈希索引是基於哈希表實現的,只能精準匹配索引的全部列的查詢時纔會生效。在Mysql中,只有Memory引擎顯式的支持哈希索引,這也是Memory引擎的默認索引類型,同時Memory引擎也支持B-Tree索引。指針
由於哈希索引自身只須要存儲對應的哈希值,因此索引的結構會十分的緊湊,這也讓哈希索引的查找速度變的很是快。可是哈希索引在使用時也有它的一些限制:code
在InnoDB引擎中有個特殊的功能叫「自適應哈希索引(adaptive hash index)」。說的是當InnoDB注意到某些索引值被應用的很是頻繁的時候,它會在內存中基於B-Tree索引之上再建一個哈希索引,這樣會讓B-Tree索引也具備一部分的哈希索引的優勢,好比快速的哈希查找。不過這是一個徹底自動的引擎內部的行爲,用戶沒法控制或配置。
MyISAM表支持空間索引,能夠用做地理數據存儲。這類索引無需前綴查詢,空間索引會從全部維度來索引數據。查詢時,能夠有效的使用任意維度來組合查詢。可是必需要使用MYySQL的GIS相關函數來維護數據。MySQL的GIS支持的並不完善,由於大部分人不會去使用這個特性。
全文索引時一種特殊類型的額索引,它查找的是文本中的關鍵詞,而不是直接比較索引中的值。全文搜索和其餘幾類索引的匹配方式徹底不同。全文索引更相似於搜索引擎作的事情,而不是簡單的where查詢條件匹配。
在相同的列上同時建立全文索引和基於值的B-Tree索引不會有衝突。