MySql的InnoDB的三層B+樹可以儲存兩千萬左右條資料的計算邏輯
總結/朱季謙
B+樹是一種在非葉子節點存放排序好的索引而在葉子節點存放資料的資料結構,值得注意的是,在葉子節點中,儲存的並非只是一行表資料,而是以頁為單位儲存,一個頁可以包含多行表記錄。非葉子節點存放的是索引鍵值和頁指標。
那麼,在MySql資料庫裡,一個頁的大小是多少呢?
可以通過查詢語句進行檢視:show variables like 'innodb_page_size'
查詢結果16384位元組,可以通過1kb等於1024位元組方式,計算出16384/1024 = 16kb,說明MySql資料庫預設頁大小是16kb。
假設一行資料佔用1kb的空間大小,然而實際上,除去欄位很多的寬表外,其實很多簡單的錶行記錄都遠達不到1kb空間佔比。這裡我們用最壞的情況來假設一行記錄大小為1kb,那麼,一個16kb的頁就可以儲存16行資料。
接下來,我們先畫一個只要兩層高的B+樹結構圖。
假設第一層根節點存在以下情況:索引1對應頁指標地址10,索引5對應頁指標地址30,索引8對應頁指標地址50。
第二層節點作為葉子節點,存放的是大小為16kb的頁資料,頁資料裡每一行記錄大小為1kb,那麼,一個葉子節點的頁裡就可以存放16條資料。
既然已經知道一個葉子節點的頁中可以存放16條資料,那麼,只需要知道根節點存在多少頁地址指標即可,就能通過 “根節點頁地址指標數量 * 單個葉子節點記錄行數”。
那麼,根節點能存放多少個 索引:頁地址指標的資料呢?
在一個節點大小為16kb的情況下,我們只需要知道索引鍵值和頁地址指標兩者大小總和即可。
根據一些資料得知,在MySql資料庫當中,指標地址大小為6位元組,若索引是bigint型別,那麼就為8位元組,兩者加起來總共是14位元組。
接下來,通過以下計算步驟,就可以統計出兩層的B+數大概可以儲存多少條記錄資料——
一、先計算一個節點的位元組大小:16kb * 1024 = 16384 位元組。
二、16384 位元組 / 14 位元組 = 1170 ,意味著,根節點有1170個頁地址指標,然後,每個頁地址指標指向的葉子節點可以存放16條資料。
三、那麼,根據“根節點頁地址指標數量 * 單個葉子節點記錄行數”,計算1170 * 16 = 18720 條記錄,可見,兩層B+數可以存放18720條記錄,當然,這個數字是存在出入的,只是作為參考。
既然已經知道兩層B+數可以存放18720條資料,那麼,三層不就可以進一步算出了嗎?
簡單畫一個三層B+數的存放資料計算邏輯——
一、根節點最多有1170個指標數;
二、說明第二層最多會有1170個子節點,同時,每個子節點裡最多有1170個指標數;
三、那麼,第三層葉節點數量,可以通過 “第二層最多有1170個節點數量 * 每個節點裡最多有1170個指標數量”,也就是1170 * 1170
四、最後,計算第三層所有葉子數量 * 各個葉子節點存放的16條資料;
最後,1170 * 1170 * 16 = 21902400,得出兩千萬左右條資料。
綜上所述,若面試當中遇到這樣問題,可以按照這個流程計算回答。
- 記一次批量更新整型型別的列 → 探究 UPDATE 的使用細節
- 編碼中的Adapter,不僅是一種設計模式,更是一種架構理念與解決方案
- 執行緒池底層原理詳解與原始碼分析
- 30分鐘掌握 Webpack
- 線性迴歸大結局(嶺(Ridge)、 Lasso迴歸原理、公式推導),你想要的這裡都有
- Django 之路由層
- 【前端必會】webpack loader 到底是什麼
- day42-反射01
- 中心化決議管理——雲端分析
- HashMap底層原理及jdk1.8原始碼解讀
- 詳解JS中 call 方法的實現
- 列印 Logger 日誌時,需不需要再封裝一下工具類?
- 初識設計模式 - 代理模式
- 設計模式---享元模式
- 密碼學奇妙之旅、01 CFB密文反饋模式、AES標準、Golang程式碼
- [ML從入門到入門] 支援向量機:從SVM的推導過程到SMO的收斂性討論
- 從應用訪問Pod元資料-DownwardApi的應用
- Springboot之 Mybatis 多資料來源實現
- Java 泛型程式設計
- CAS核心思想、底層實現