總結
1.mysql對這個節點大小設置的是16K,用下面這個SQL就是可以查到 show global status like 'Innodb_page_size'
2.樹的高度只有3的情況下就能存儲2千多萬的數據,而且mysql底層的索引他的根節點,是常駐內存的,直接就放到內存的。所以次數再減去1,2次即可。
- 假設索引字段類型是Bigint,8bit,每兩個元素之間存的是下一個節點的地址,mysql分配的是6bit,也就是說一個索引后面配對一個節點地址,成對出現,可以算一下16K的節點可以存多少對也就是多少個索引,8b+6b=14b,16K /14b=1170個索引,葉子節點有索引有data元素,假設占1K,那一個節點就放16K/1K=16個元素,假設樹高是3,所有節點都放滿,能放多少數據?可以算一下,1170*1170*16=21902400,2千多萬,mysql設置16K的大小,數據就可以存2千多萬就已經足夠了吧,既能保證一次磁盤IO不要Load太多的數據 又能保證一次load的性能,即便表的數據在幾千萬的數量也能保證樹的高度在一個可控的范圍。

細節
可不可以把一個表的數據都放到一個大的節點上?然后把這個節點一次性load到內存里,我再在內存里一個個去比對不行嗎?不是說內存里去比較查找元素是非常的快嘛,跟一次磁盤IO去比對快的多。不可以這樣嗎?
答案是否定的。
凡事都有個度。你想想,假如我們有幾千萬數據,在磁盤上面全部放到一個節點上去是不可能的,你的數據表是一行行插入的,存在磁盤上面幾百兆甚至幾個G,一次性load到內存中合適嗎?內存本來就有限,一次性load這么大的數據,而且如果你學過計算機組成原理你也知道,磁盤IO跟內存打交道的單位是4K,一次可能讀取4K的數據,可能有時候有一些局部讀取的原理可能會取幾十K(4K的整數倍),取個16K,24K也是可以的 。但是一次交互取這么大是搞不定的,這是計算機組成原理定的,一次磁盤IO取那么多數據,對內存也是非常的浪費,而且這一次磁盤IO也是非常慢的。所以這個節點的大小設置要合適,不能太大也不能太小,mysql對這個節點大小設置的是16K,用下面這個SQL就是可以查到 show clobal status like 'Innodb_page_size' 。

為啥設置16K?為什么不是更大的如16M呢,16K已經足夠用了。
假設索引字段類型是Bigint,8bit,每兩個元素之間存的是下一個節點的地址,mysql分配的是6bit,也就是說一個索引后面配對一個節點地址,成對出現,可以算一下16K的節點可以存多少對也就是多少個索引,8b+6b=14b,16K /14b=1170個索引,葉子節點有索引有data元素,假設占1K,那一個節點就放16K/1K=16個元素,假設樹高是3,所有節點都放滿,能放多少數據?可以算一下,1170*1170*16=21902400,2千多萬,mysql設置16K的大小,數據就可以存2千多萬就已經足夠了吧,既能保證一次磁盤IO不要Load太多的數據 又能保證一次load的性能,即便表的數據在幾千萬的數量也能保證樹的高度在一個可控的范圍。
可以看一下幾千萬的數據表是不是加了索引幾十毫秒幾百毫秒就出結果了,所以就解釋了幾千萬的表精確的使用索引后他的性能依舊比較高。
樹的高度只有3的情況下就能存儲2千多萬的數據,即便某一個索引在葉子節點,那也就2、3次磁盤IO就能查找到,當然很快了。而且mysql底層的索引他的根節點,是常駐內存的,直接就放到內存的,查找葉子節點,一個2千萬的數據放到B+Tree上面,要查找葉子節點,就只需要2次磁盤IO就搞定了,在內存里比對的時間基本可以忽略。
