查看 InnoDB表中每個的索引高度

jopen 8年前發布 | 8K 次閱讀 InnoDB MySQL 數據庫服務器

這個問題最早在Inside君的IMG微信群中進行討論,經過為期2周的討論,結合群內小伙伴的集體智慧,終于克服了這個問題。此問題的起源是很多小伙伴都會問Inside君,如何查看InnoDB的索引樹的高度,在我的書中 《MySQL技術內幕:InnoDB存儲引擎》 中,我寫到一般樹的高度在3~4層之間,但是并沒有給出證明的手段或者方法。InnoDB也沒有提供相應的視圖進行查看。其實明白InnoDB索引的構造,就能迅速得出索引的高度。

InnoDB是索引組織表,每個頁都包含一個PAGE_LEVEL的信息(見上圖右半部分),用于表示當前頁所在索引中的高度。默認葉子節點的高度為0,那么root頁的PAGE_LEVEL + 1就是這棵索引的高度。接下去的問題就是怎樣得到一張表所有索引的Root頁所在的位置呢?看過Inside君的 《MySQL技術內幕:InnoDB存儲引擎》 都知道(space,3)這個頁是聚集索引的root,并且在 《MySQL內核:InnoDB存儲引擎 卷1》 中也已經說過,Root頁的位置通常是不會更改的。那么其他索引的Root頁所在的位置呢?

其實官方提供了內部視圖來查看每個索引的Root頁,但可惜的是大部分DBA們都不知道,亦或許是因為覺得沒啥用吧,通過下面的SQL語句可以查出某這表對應索引的Root頁:

SELECT
b.name, a.name, index_id, type, a.space, a.PAGE_NO
FROM
information_schema.INNODB_SYS_INDEXES a,
information_schema.INNODB_SYS_TABLES b
WHERE
a.table_id = b.table_id AND a.space <> 0;

運行上述的SQL語句應該可以得到類似如下的結果:

其中(SPAE,PAGE_NO)就是索引的Root頁。SPACE,PAGE_NO對應的含義還不知道?那趕快來上Inside君的MySQL培訓班吧,最好的MySQL培訓班,過完年 深圳線下班 就將開啟。

有了這些信息就可以方便的定位啦,因為PAGE_LEVEL在每個頁的偏移量64位置出,占用兩個字節,通過hexdump這樣的工具就可以快速定位到所需要的樹高度信息:

root@test-1:~# hexdump -s 24640 -n 10 customer.ibd
00006040  00 02 00 00 00 00 00 00  00 47  

查看customer表,24640表示的是3*8192+64(這里innodb_page_size設置為了8192,并非默認的16384),即第3個頁偏移量64位置開始讀取10個字節,但不是讀取2個字節就可以了嘛?其實因為后面8個字節對應的是index_id,就是上圖中看到的index為71的索引,這里PAGE_LEVEL為00 02,那么索引的高度就為3。

用同樣的方法可以查看customer表中i_c_nationkey的索引高度:

root@test-1:~# hexdump -s 32832 -n 10 customer.ibd
00008040  00 01 00 00 00 00 00 00  00 48  

可以發現PAGE_LEVEL為00 01,表示這棵二級索引樹的高度為2。

雖然通常來說索引樹的高度為3~4層,但是極端情況下,比如數據量超級大,頁比較小,如4K,那么高度也是可能破4的。那么現在是不是可以來比比誰家的索引樹最高呢?

最后,IMG微信群會定期放出一些討論問題,非常具有挑戰,各位有態度的小伙伴要不要來挑戰看看呢?可惜微信群已滿,只能通過Inside君的邀請(Inside君的個人微信號:82946772),趕快加入這個有態度的IMG社區吧。

來自: http://www.innomysql.net/article/25252.html

 本文由用戶 jopen 自行上傳分享,僅供網友學習交流。所有權歸原作者,若您的權利被侵害,請聯系管理員。
 轉載本站原創文章,請注明出處,并保留原始鏈接、圖片水印。
 本站是一個以用戶分享為主的開源技術平臺,歡迎各類分享!