以MySQL InnoDB為例。InnoDB存儲引擎最小儲存單元是頁,一頁大小固定是16KB,使用該引擎的表為索引組織表。B+樹葉子存的是數據,內部節點存的是鍵值和指針。索引組織表通過非葉子節點的二分查找法以及指針確定數據在哪個頁中,進而再去數據頁中找到需要的數據。
如果B+樹的高度為2,即有一個根節點和若干個葉子節點,則這棵B+樹的存放總記錄數為:根節點指針數 * 單個葉子節點記錄行數。
假設一行記錄的數據大小為1KB,那么單個葉子節點可以存的記錄數 =16KB/1KB =16。非葉子節點內可以存放多少指針呢?假設主鍵ID為bigint類型,長度為8字節,而指針大小在InnoDB源碼中設置為6字節,所以就是一個鍵值指針占用8+6=14字節,一個內部節點中存儲的指針個數為 16KB/14B = 16 * 1024B / 14B = 1170。因此,一棵高度為2的B+樹,能存放 1170 * 16 = 18720 條這樣的數據記錄。同理一棵高度為3的B+樹,能存放 1170 *1170 *16 = 21902400,大概兩千萬左右的記錄。
B+樹高度一般為1-3層,如果到了4層,查詢時會增加查磁盤的次數,數據尋找就會變慢。因此如果單表數據量太大,SQL查詢變慢,就需要考慮分表了。