1. 索引操作
2. 索引類型
- PRIMARY
唯一且不能為空;一張表只能有一個主鍵索引 - INDEX
普通索引 - UNIQUE
唯一性索引 - FULLTEXT
全文索引:用於搜索很長一篇文章的時候,效果最好。用在比較短的文本,如果就一兩行字的,普通的 INDEX 也可以
3. 聚集索引 VS 非聚集索引
3.1 區別
* 聚集索引:主鍵索引,索引中鍵值的邏輯順序決定了表中相應行的物理順序
* 非聚集索引(非主鍵索引,也稱二級索引):除主鍵索引(普通索引、唯一索引、全文索引),索引的邏輯順序與磁盤上行的物理存儲順序不同
查詢過程:
- 查詢聚集索引能直接得到所有數據,
- 查非聚集索引需要先得到聚集索引地址,回表 再得到數據。
3.1 聚集索引規則
- 如果一個主鍵被定義了,那么這個主鍵就是作為聚集索引
- 如果沒有主鍵被定義,那么該表的第一個唯一非空索引被作為聚集索引
- 如果沒有主鍵也沒有合適的唯一索引,那么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_[字段名]_[字段名]...