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萬數據,樹有多高?
InnoDB頁的大小默認是16k,16k=16384byte,一般一行數據為1k,單個葉子節點(頁)的記錄數為16/1 = 16,假設主鍵id為bigint8字節,指針大小默認為6字節,一頁能存放 16384/14 = 1170 高度為2的能存放 1170*16 = 18720 高度為3的能存放 1170*1170*16= 21902400

5. 覆蓋索引

select 主鍵 from table where 普通索引字段 = ** ;

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

例子:身份證號 和 姓名

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

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

6. 最左前綴原則

兩個概念:

  • 這個最左前綴可以是 組合索引的最左N個字段
  • 也可以是 字符串索引的最左M個字符

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

只要能匹配到最左N個字段,則能使用索引。 如 [a,b,c] [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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM