1. 程式人生 > 程式設計 >Mysql索引進階入門

Mysql索引進階入門

1. 索引操作

MySQL 索引 菜鳥

2. 索引型別

  • PRIMARY 唯一且不能為空;一張表只能有一個主鍵索引
  • INDEX 普通索引
  • UNIQUE 唯一性索引
  • FULLTEXT 全文索引:用於搜尋很長一篇文章的時候,效果最好。用在比較短的文字,如果就一兩行字的,普通的 INDEX 也可以

3. 聚集索引 VS 非聚集索引

3.1 區別

* 聚集索引:主鍵索引,索引中鍵值的邏輯順序決定了表中相應行的物理順序
* 非聚集索引(非主鍵索引,也稱二級索引):除主鍵索引(普通索引、唯一索引、全文索引),索引的邏輯順序與磁碟上行的物理儲存順序不同
複製程式碼

查詢過程:

  • 查詢聚集索引能直接得到所有資料,
  • 查非聚集索引需要先得到聚集索引地址,回表 再得到資料。

3.1 聚集索引規則

  1. 如果一個主鍵被定義了,那麼這個主鍵就是作為聚集索引
  2. 如果沒有主鍵被定義,那麼該表的第一個唯一非空索引被作為聚集索引
  3. 如果沒有主鍵也沒有合適的唯一索引,那麼innodb內部會生成一個隱藏的主鍵作為聚集索引,這個隱藏的主鍵是一個6個位元組的列,改列的值會隨著資料的插入自增。

4 索引結構

預設 B+Tree,Hash(key-value的插入以及查詢,雜湊表的時間複雜度都是O(1),如果不需要有序的遍歷資料,雜湊表效能最好。)

B+樹 由二叉樹演變的m階樹

為什麼是B+樹(配合磁碟的讀寫特性,減少單次查詢的磁碟訪問次數。)

4.1 B+樹特點

———— 極客時間 資料結構與演演算法之美

  • 每個節點中子節點的個數不能超過 m,也不能小於 m/2;
  • 根節點的子節點個數可以不超過 m/2,這是一個例外;
  • m 叉樹只儲存索引,並不真正儲存資料,這個有點兒類似跳錶;
  • 通過連結串列將葉子節點串聯在一起,這樣可以方便按區間查詢;
  • 一般情況,根節點會被儲存在記憶體中,其他節點儲存在磁碟中。

複雜度

  • 所有操作(查、插、刪) 時間複雜度 O(logm(N)),
  • 空間複雜度 最差 O(n)

4.2 m階怎麼計算來?

作業系統按頁讀取(預設是4k或者8k),為了提高I/O效率,所以一個索引頁和作業系統讀取空間保持一致。

m = 資料頁大小/索引項大小
複製程式碼

所以索引項欄位佔空空間越小(int 4byte,比bigint 8byte少一半),一頁存的索引資料越多,在優化的時候也要考慮索引欄位的長度。

子節點是 雙向連結串列 結構,方便範圍查詢及排序。

考慮: 1000萬資料,樹有多高?

5. 覆蓋索引

select 主鍵 from table where 普通索引欄位 = ** ;
複製程式碼

覆蓋索引概念:通過索引直接插到結果,不需要回表操作。

例子:身份證號 和 姓名

如果要根據身份證號查詢資訊,只要在身份證上建立索引,需要建[身份證、姓名] 組合索引嗎?

如果有身份證號查詢姓名的高頻查詢,則建立上邊的組合索引,則可達到覆蓋索引,不需要回表查到整行資料,減少執行時間。

6. 最左字首原則

兩個概念:

  • 這個最左字首可以是 組合索引的最左N個欄位
  • 也可以是 字串索引的最左M個字元

建立組合索引(a,b,c)相當於建立了 (a,c) (a,b) (a,c) (a) 四個索引

只要能匹配到最左N個欄位,則能使用索引。 如 [a,c] [a,b] [a] 都能觸發索引,內部順序可變,mysql自動調整。

字串索引 最左M個字元:如like x% ok,%x,%x% 不行。

7. 索引下推

MySQL 5.6 引入的索引下推優化(index condition pushdown)

可以在索引遍歷過程中,對索引中包含的欄位先做判斷,直接過濾掉不滿足條件的記錄,減少回表次數。

8. 索引是否生效,優化

可以使用 EXPLAIN 來分析索引是否起效,慢sql做一些索引優化 Explain優化查詢檢測

  • 索引欄位為int型別時,條件可用' '包起來 也可以直接是數值比較

  • 索引欄位為varchar型別時,條件要使用' '包起來

  • 能觸發range範圍索引 >,<,not in,in,!=,BETWEEN AND (5.5後版本 )

9. 常用索引命名規範

唯一 uk_[欄位名]_[欄位名]...
普通 idx_[欄位名]_[欄位名]...
複製程式碼

github blog