InnoDB之索引簡述

1. InnoDB中用到的索引是B+樹,回顧一下B+樹的知識。

2. 聚集索引

每張InnoDB表都會有一個聚集索引用于指定行數據存放的順序。默認情況下,InnoDB以表的主鍵作為聚集索引,即該表按照主鍵的大小順序進行存儲的。而聚集索引就是以主鍵構造的一顆B+樹,且葉子節點就是行數據本身。

InnoDB聚集索引的選取:
如果表有主鍵則主鍵就是聚集索引,如果沒有則選取第一個UNIQUE索引且索引對應的行是NOT NULL的,如果還沒有,則系統自動生成。

1. 聚集索引的特點:

  • 由于一張表的排列順序只有一種,所以一張表也最多只能有一個聚集索引
  • 我們創建表時,無法手動指定聚集索引的。

2. 聚集索引的優點

  • 由于葉子節點存放的就是行數據本身,所以查找只需要一次遍歷B+樹就可以找到
  • 對聚集索引字段的排序和范圍查找很快
    • 排序:因為聚集索引已經是排好序的,所以無需再進行排序操作。
    • 范圍:我們只需要找到范圍的兩端,且由于葉子節點是一個雙向鏈表,且是數據本身,所以兩端葉子之間的葉子節點就是結果。

3. 非聚集索引

除了聚集索引的索引都叫非聚集索引。
非聚集索引和聚集索引的區別就是葉子節點存放的數據。且非聚集索引顯然一張表可以有多個的。

  • 聚集索引葉子節點存放的是行數據本身。
  • 非聚集索引葉子節點存放的是聚集索引的值。
    所以對非聚集索引的查找[通常情況下]至少要經過兩次B+樹的遍歷。且范圍查找時,找到所有符合條件的聚集索引值之后,需要依次對每個聚集索引值找到對應的數據。

MyISAM引擎表不存在聚集索引,所有的索引的葉子節點存放的都是行數據的地址,即每次查找通過B+樹找到數據的地址,然后再根據地址找到具體的數據。

4. 聯合索引

如果有一個聯合索引(a,b),則就會建一個這樣的組合樹,樹的節點每個“值”都是一個數值對,而且按照a的大小順序排的,當a相等時,才會根據b的大小排。如圖。


聯合索引

所以(a,b)索引時,可以單獨查a也會走索引。而如果單獨查b則不會走索引。

  • 聯合索引的第二個好處:
    已經對第二個鍵做好了排序,比如:
select * from t where a = 5 order by b

其實order by b這步是不需要進行任何額外開銷的,因為聯合索引已經對b做好了排序了,所以直接取a = 5就可以了。

5. 覆蓋索引

InnoDB是支持覆蓋索引的,即從非聚集索引中就可以得到想要的結果,而不需進行回聚集索引查詢。
這樣的情況有兩種:

1. 根據非聚集索引的條件查詢聚集索引對應列的值

例如:加入a是聚集索引,b是非聚集索引

select a from t where b = 2;

我們知道非聚集索引葉子節點存的就是聚集索引的值,所以這個查詢只需進行一次B+樹搜索就可以了。

2. 某些統計問題

因為非聚集索引存的只是聚集索引的值,而聚集索引存的是整個行數據,所以非聚集索引的大小要遠遠小于聚集索引,小就意味著更少的IO。所以如果可以通過非聚集索引完成的事,就不要使用聚集索引。
例如:假設t有主鍵a,和非聚集索引b

select count(*) from t;

這條語句使用的就是b,因為b更小更高效。

覆蓋索引有個特點:
  • 使用explain進行執行過程分析時,extra字段是using index
  • 一般情況下,聯合索引(a,b),根據b的查詢不會用到這個聯合索引,但如果查詢的是count就可能會用到。
select count(*) from t where b = 2;

用到這個索引的原因是因為非聚集索引很小,查詢的效果快。

6. 索引提示

當InnoDB最終使用的index并不是最優的時(這種情況幾乎不會出現),我們可以給它一些提示,建議它用某個索引。

select * from t user index(ix_a) where a = 1;

注意這里只是建議它使用,最終使用的索引還是由InnoDB自己決定。

對之對應的還有force index,即強制這條查詢語句使用某個索引。

select * from t force index(ix_a) where a = 1;
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容