数据库索引高频面试题梳理
引言
數據庫索引的重點知識梳理~
1、索引是什么,有什么作用,有何優缺點?
索引是幫助Mysql高效獲取數據的一種數據結構,通常用B樹,B+樹實現(Mysql不支持hash)
2、為什么用B+樹而不用B樹,B+樹有什么優勢?
(1)IO代價更低。B+樹由于非葉子節點中不存放data,因此可以存放更多的索引值(單個大節點的容量固定,每個小單位size變小了),從而使得樹的高度更低,磁盤IO次數更少。
(2)查詢效率穩定。B+樹由于所有data都放在葉子節點中,因此每次查詢都要走完整的根節點到葉子節點的路徑,所有查詢的路徑長度相同,查詢效率更加穩定。
(3)更利于范圍查詢。B+樹葉子節點之間有指針,注意是雙向的指針,更利于范圍查詢。
案例分析:索引如何支撐千萬級表的快速查找?(B+樹)
Mysql底層用B+樹存儲索引,假設現在用3層B+樹來存儲(層數越少,磁盤I/O次數越少),我們來看一共能存多少行數據:
(1)Mysql規定一個頁面大小為16KB(即圖中一個大節點),假設現在存的數據字段是bigint型的,占8B,指針根據底層源碼規定占6B,則一個大節點一共可以存放索引記錄共16KB/(8+6)B=1170,則葉子節點的節點個數共有1170x1170個。
(2)假設葉子節點中一個索引+data占用1KB,則一個節點中可存放索引+data記錄共16KB/1KB=16個。
(3)因此葉子節點層一共能存放索引+data記錄數目為1170*1170*16=2190 2400
(4)因此3層B+樹即可存放兩千萬以上的數據
3、為什么用B+樹索引而不用哈希索引?
哈希索引,建立的是索引值的哈希值和物理磁盤地址之間的映射
(1)哈希沖突多的時候,性能也不一定就比B+樹好
(2)哈希索引不支持范圍查詢,只能點對點查詢,哈希運算前的索引值和哈希運算后的哈希值順序并不一定一樣
(3)哈希索引不能利用部分索引鍵查詢,哈希索引在計算哈希值的時候是組合索引鍵合并后再一起計算哈希值,而不是單獨計算哈希值,所以通過組合索引的前面一個或幾個索引鍵進行查詢的時候,哈希索引也無法被利用
4、為什么InnoDB推薦用整型自增主鍵,而不是uuid?
(1)uuid占用空間更多。uuid是隨機字符串,占用空間更多,整型更少。
(2)uuid排序不如整型容易。uuid是字符串,而節點中的索引值需要排序,顯然整型排序更容易。
(3)整型自增插入時可避免節點頻繁分裂。插入數據時,自增主鍵對B+樹結構影響很小,由于是遞增,往后加就行,而uuid是隨機的,可能插到中間,如果前面節點已經滿了,會導致節點分裂(頁分裂)、樹結構調整等大量耗費性能的操作。
聚簇索引和非聚簇索引
索引可分為兩個大類:
- 主鍵索引:主鍵本身就是一個索引
- 輔助索引(也稱為非主鍵索引、二級索引):設置主鍵之外的其他字段為索引
聚簇索引定義:
非聚簇索引定義:
記住一個結論:
- InnoDB使用的都是聚簇索引
- Myisam使用的都是非聚簇索引
InnoDB的主鍵索引是嚴格的聚簇索引,B+樹葉子節點中存放主鍵索引值和對應數據行所有字段。非主鍵索引不是嚴格的聚簇索引但也歸為其中,B+樹葉子節點中存放的是非主鍵索引值和對應主鍵值。因此InnoDB中使用非主鍵索引來查詢數據,需要查兩棵B+樹。
Myisam的主鍵索引和非主鍵索引都是非聚簇索引,B+樹葉子節點中存放的都是索引值和對應數據行的物理磁盤地址
下面兩張圖非常直觀理解:
注意:如果有人問Innodb輔助索引是不是非聚簇索引,可以這么回答:從定義的角度innodb的輔助索引確實不算是嚴格的聚簇索引,但它和Myisam的輔助索引并不相同,一個存的數據行物理磁盤地址,一個存的是主鍵值。一般不會這么問,因為聚集索引主要是用來區分Innodb和Myisam的,不會單獨針對輔助索引再胡攪蠻纏
為什么Innodb的輔助索引不直接存數據物理地址,其相對于Myisam的索引有何優勢?
(1)為什么不存所有數據?節省存儲空間
(2)為什么不存數據地址值?如果存的是物理地址,那么當表中數據行有位置移動時(例如不斷插入數據時,會涉及節點分裂,物理地址會變化),就需要去更新葉子節點中存的這個物理地址值。如果存的是主鍵,如果有行移動,輔助索引樹不需要有任何變動,減少了維護開銷
總結
以上是生活随笔為你收集整理的数据库索引高频面试题梳理的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: c++ 2D小球 碰撞模拟
- 下一篇: ctfmon.exe频繁出错的一个解决办