earcharts tree 节点间隔_InnoDB是顺序查找B-Tree叶子节点的吗?
導(dǎo)讀
在《為什么MySQL能夠支撐千萬數(shù)據(jù)規(guī)模的快速查詢?》中,我詳細(xì)講解了InnoDB B-Tree的結(jié)構(gòu),同時(shí),我以下面這條SQL舉例:
SELECT * FROM user WHERE age >= 15講解了該查詢是如何搜索輔助索引index_age_birth這顆索引樹的。其中,我在查找葉子節(jié)點(diǎn)時(shí),說到從節(jié)點(diǎn)內(nèi)第一條記錄開始,向右遍歷該節(jié)點(diǎn)內(nèi)所有記錄即可定位到滿足條件的第一條記錄,然后,遍歷該記錄后繼所有記錄,即可得到滿足條件的所有記錄。
但是,如果葉子節(jié)點(diǎn)內(nèi)的記錄太多,而滿足條件的第一條記錄又不在頭部位置,那么,順序遍歷查找的性能是很差的。該如何解決這個(gè)問題呢?我想,你可能已經(jīng)猜到了,是的,由于葉子節(jié)點(diǎn)的記錄是升序排列的,我們完全可以用二分查找,快速定位到滿足條件的第一條記錄。
那么,InnoDB具體是怎么做的呢?
槽
我以用戶表索引index_age_birth為例,先來看一下該索引葉子節(jié)點(diǎn)的結(jié)構(gòu):
見上圖,跟之前我講的輔助索引B-Tree的葉子節(jié)點(diǎn)是不是不一樣?是的,之前我講的比較粗,現(xiàn)在我把它細(xì)化了,為了詳細(xì)講解一個(gè)查詢是如何在B-Tree的葉子節(jié)點(diǎn)中定位一條記錄的。
我們來仔細(xì)看下上面這張圖,相比之前的葉子節(jié)點(diǎn),這張圖多出來三個(gè)元素:
(1) 槽內(nèi)存儲(chǔ)的是一個(gè)偏移量,這個(gè)偏移量是從葉子節(jié)點(diǎn)0字節(jié)開始計(jì)算的。比如:
? a. 圖中的99,表示從葉子節(jié)點(diǎn)0字節(jié)開始第115字節(jié)的位置為槽0。
? b. 圖中的252,表示從葉子節(jié)點(diǎn)0字節(jié)開始第99字節(jié)的位置為槽1。
? c. 圖中的112,表示從葉子節(jié)點(diǎn)0字節(jié)開始第220字節(jié)的位置為槽2。
為啥需要偏移量?為了根據(jù)偏移量定位該偏移量位置所在的記錄。
(2) 一個(gè)槽指向一個(gè)分組中的最大記錄。比如,圖中,橘色框代表分組,所以,槽1指向第二個(gè)分組的最大記錄<17, 2007-06-10, 11>。
(3) 槽與槽之間組成一個(gè)無序數(shù)組,但槽的下標(biāo)是有序的。比如,圖中,99、252、112這3個(gè)偏移量是無序的,但是,槽的下標(biāo)0、1、2是有序的。
這時(shí),你可能會(huì)有個(gè)疑問:為什么第一個(gè)分組只有1條記錄,第二個(gè)分組有4條記錄,而最后一個(gè)分組有2條記錄?
因?yàn)镮nnoDB引擎規(guī)定:對(duì)于infimum記錄所在的分組只能有 1 條記錄,supremum記錄所在的分組擁有的記錄條數(shù)只能在 1~8 條之間,剩下的分組中記錄的條數(shù)范圍只能在是 4~8 條之間。
下面,我結(jié)合槽的結(jié)構(gòu)定義,詳細(xì)講解InnoDB在葉子節(jié)點(diǎn)中定位記錄的過程。
查找過程
InnoDB查找葉子節(jié)點(diǎn)的過程采用的是對(duì)槽二分查找,槽所指記錄所在分組內(nèi)順序查找的方式。至于為什么槽內(nèi)不用二分查找,是因?yàn)椴壑赶虻挠涗浰诜纸M記錄總數(shù)不會(huì)超過8條,所以,沒必要使用二分查找來提升查找性能。
我以本章《導(dǎo)讀》中的SQL為例,詳細(xì)講解InnoDB在葉子節(jié)點(diǎn)中如何查找第一條滿足查詢條件的記錄。
SELECT * FROM user WHERE age >= 15見下面5張圖,其中的葉子節(jié)點(diǎn)都是索引index_age_birth這個(gè)B-Tree的,頁4是通過B-Tree搜索定位的葉子節(jié)點(diǎn):
說明:
在這個(gè)查找過程中,你可能有個(gè)疑問,我都已經(jīng)在第5步找到了滿足條件的第一條記錄,為什么還要進(jìn)行第6步?
因?yàn)檫@個(gè)查找過程是一個(gè)通用算法,假設(shè)我們要查找age = 16的記錄,那么,頁4中包含兩條滿足條件的記錄,結(jié)合上面的查找算法,是不是要執(zhí)行到第6、7步才能找到所有匹配的記錄?!所以,InnoDB采用了該通用查找算法,覆蓋age >= 15和age = 16兩個(gè)場(chǎng)景。
小結(jié)
最后,我來總結(jié)一下本章講解的內(nèi)容:
思考題
InnoDB直接對(duì)葉子節(jié)點(diǎn)記錄進(jìn)行二分查找不香嗎?為什么要引入槽的概念查找索引樹葉子節(jié)點(diǎn),即對(duì)槽二分查找,槽指向記錄所在的分組內(nèi)順序查找?
總結(jié)
以上是生活随笔為你收集整理的earcharts tree 节点间隔_InnoDB是顺序查找B-Tree叶子节点的吗?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: flash写保护原理_老司机带路:LPC
- 下一篇: numpy 图片填充_numpy/pyt