談談MySQL 索引

一、索引是什麼

索引(Index)是幫助MySQL高效獲取數據的數據結構。咱們能夠簡單理解爲:索引的目的在於提升查詢效率。html

二、原理

索引的數據結構是B+樹,原理圖以下
B+樹mysql

關於B+樹的詳細介紹,能夠參見文章下面的參考。sql

精簡描述:B+樹是爲了磁盤或其餘直接存儲輔助設備設計的一種平衡查找樹。在B+樹中,全部記錄節點都是按鍵值的大小順序存放在葉子節點上,各葉子節點直接由指針進行鏈接。數據結構

B+樹中的B不是表明二叉(binary),而是表明平衡(balance),由於B+樹是從最先的平衡二叉樹演化而來,可是B+樹不是一個二叉樹。性能

索引的內部也是一張表,索引組織表,索引的構建須要使用到磁盤空間跟內存空間,並非索引越多越好,太多反而致使性能降低,建議一張表最多不要超過8個索引。優化

三、索引分類

下面的分類維度沒有標準,但通常索引咱們會比較關注彙集索引跟非彙集索引。設計

3.1 彙集索引

彙集索引(clustered index)是按照每張表的主鍵構造一棵B+樹,同時葉子節點中存放的即爲整張表的行記錄數據,也將彙集索引的葉子節點稱爲數據頁。指針

因爲實際的數據頁只能按照一棵B+樹進行排序,所以每張表只能擁有一個彙集索引。htm

主鍵是一個彙集索引,若是在InnoDB沒有定義主鍵,那麼默認生成一個rowId做爲彙集索引。blog

3.2 非彙集索引

非彙集索引(Secondary Index,也稱輔助索引),葉子節點並不包含行記錄的所有數據。葉子節點除了包含鍵值之外,每一個葉子節點中的索引行中還包含了一個書籤(bookmark)。該書籤用來告訴InnoDB存儲引擎哪裏能夠找到與索引相對應的行數據。

當經過輔助索引來尋找數據時,InnoDB存儲引擎會遍歷輔助索引並經過葉級別的指針得到指向主鍵索引的主鍵,而後再經過主鍵索引來找到一個完整的行記錄。
非彙集索引

3.3 覆蓋索引

從輔助索引中就能夠獲得查詢的記錄,而不須要查詢彙集索引中的記錄。

使用覆蓋索引的好處是輔助索引不包括整行記錄中的全部信息,能夠減小IO操做。

3.4 惟一索引

不容許具備索引值相同的行,從而禁止重複的索引或鍵值。

3.5 聯合索引

聯合索引是指對錶上的多個列進行索引。從本質上來講,聯合索引也是一顆B+樹,不一樣的是聯合索引的鍵值的數量不是1,而是大於等於2。

索引匹配的原則是最左匹配原則,MySQL會一直向右匹配直到遇到範圍查詢(>、<、between、like)就中止匹配。

如創建了索引(a,b,c),那麼這些條件語句是能夠走到這個索引的,「a=1 and b = 2 and c > 3」、「a=1 and b = 2」,但「b > 1 and d = 10」就沒有走到這個索引了,第一個命中的必須是「a」。

四、索引的使用

4.1 選擇性:

count(distinct colname)/count(colname) ->1,儘可能將選擇性高的列放在索引的最前面,可是也存在例外狀況。

典型的例子如性別,通常是不建索引的。

4.2 避免Null:

額外存儲,特殊處理;

使索引統計和值更加複雜;

SQL執行結果不符合預期

4.3 索引上不要作運算

select id,value from tab where id+10=15 (x)

4.4 多使用聯合索引:

將多個字段創建一個組合索引
一個索引能夠被多個query利用
減小索引數量,消除重複索引

4.5 避免負向查詢

避免使用NOT、!=、<>、!<、!>、NOT EXISTS、NOT IN、NOT LIKE等

五、索引優化

5.1 explain

使用EXPLAIN關鍵字能夠模擬優化器執行SQL查詢語句,從而知道MySQL是如何處理你的SQL語句的。分析你的查詢語句或是表結構的性能瓶頸。

通常重點看type、key、rows。

type:表示表的鏈接類型。經常使用的類型有: ALL、index、range、 ref、eq_ref、const、system、NULL(從左到右,性能從差到好)
key:表示實際使用的索引
rows:掃描出的行數(估算的行數),通常這個值越小越好

5.2 Cardinality值

索引是否具備高選擇性,通常就能夠看Cardinality值。

能夠經過「SHOW INDEX FROM table」結果中的列Cardinality來觀察,這是一個預估的值,而不是一個準確的值,是經過採樣獲得的數據。

Cardinality/總條數越接近1,越有必要建索引。

5.3 MySQL查詢優化器

MySQL 查詢優化器的主要功能是完成SELECT語句的執行,在保證SELECT語句正確執行以外,還有一個重要的功能,就是使用關係代數、啓發式規則、代價估值模型等不一樣種類的技術,提升SELECT語句的執行效率。

這部分是MySQL實現的,可讓咱們的SQL寫得更「隨意」。

參考資料

官方文檔mysql-index https://dev.mysql.com/doc/refman/5.6/en/mysql-indexes.html
官方文檔彙集索引與輔助索引 https://dev.mysql.com/doc/refman/5.6/en/innodb-index-types.html
姜承饒 《MySQL技術內幕:InnoDB存儲引擎》
MySQL索引原理及慢查詢優化 https://tech.meituan.com/2014/06/30/mysql-index.html
深刻理解什麼是B+樹 https://cloud.tencent.com/developer/article/1425602
BTree和B+Tree詳解 http://www.javashuo.com/article/p-pzosgihq-dz.html
Hollis關於Explain的講解 https://mp.weixin.qq.com/s/OpS_F5lG9CaFw4xqnofWLw
MySQL查詢優化器 https://yq.aliyun.com/articles/680912

相關文章
相關標籤/搜索