考慮表結構如下: create table testzh(id int primary key auto_increment ,id2 int,id3 int); 插入數據: delimiter // create procedure ins3() begin declare i int; set i=0; while i<10000 do insert into testzh(id2,id3) values(FLOOR((RAND()*100000)),FLOOR((RAND()*100000))); set i=i+1; end while; end; // delimiter ; 這里僅僅考慮聚合索引的B+數結構。 首先我們要考慮2個因素: 1、分支節點如何存儲一行數據 2、葉子結點如何存儲一行數據 位了找到這個問題我們必須要找到哪些塊是葉子結點,哪些塊是非葉子結點,這里使用自己寫的一個程序 找到詳細參考最后的代碼 (http://blog.itpub.net/7728585/viewspace-2128817/) [root@testmy test]# ./t1 testzh.ibd file size is 442368 Block id is 3:Index page no is 552 : B+ Tree Level is 1 Block id is 4:Index page no is 552 : B+ Tree Level is 0 Block id is 5:Index page no is 552 : B+ Tree Level is 0 Block id is 6:Index page no is 552 : B+ Tree Level is 0 Block id is 7:Index page no is 552 : B+ Tree Level is 0 Block id is 8:Index page no is 552 : B+ Tree Level is 0 Block id is 9:Index page no is 552 : B+ Tree Level is 0 ..... 可以看到在這個文件中block_id = 3的是非葉子結點 其他的塊是葉子結點。 那我們來研究第一個問題 1、分支節點如何存儲一行數據 其實這個問題答案就是 6字節固定開銷+4字節(int數據類型4字節)+4字節(指向葉子結點的指針開銷) 我們知道每個數據庫塊的前120直接是管理固定開銷如: FILE HEADER,INDEX HEADER等 在塊尾部也有8字節的固定開銷 那么我們從offset 120開始向后面數14個字節,這里也要使用我自己寫的工具 bcview 方便查看 ./bcview testzh.ibd 16 120 14 current block:00000003--Offset:00120--cnt bytes:14--data is:00100011000e8000000100000004 得到數據: 00100011000e8000000100000004 分析一下: 00100011000e8000000100000004 固定開銷(6字節) 00 nullable field bitmap (?) 10 info flags+number of records owned 0011 order+ record type (0000 0000 0001 0001) 000e 下一個偏移量 --可變開銷(實際數據4字節) 80000001 (實際主鍵數據1其中8是符號位) --固定開銷(4字節) 00000004 (葉子結點block指針) 我們可以看到這是非葉子結點存儲數據的格式如此,除了4字節的主鍵外,這里包含了10字節的額外開銷。 2、葉子結點如何存儲一行數據 接下來我們來看一下這個表的每一行數據是如何存放的,二進制如下: ./bcview testzh.ibd 16 120 31 current block:00000004--Offset:00120--cnt bytes:31--data is:00000010001f800000010000004d1995cd000001440110800046cd80000683 00 nullable field bitmap(?) 00 info flags+number of records owned 0010 order+record type 001f 下一個偏移量 80000001 (實際主鍵id數據1其中8是符號位) 0000004d1995 transaction id cd000001440110 roll pointer 800046cd (實際數據id2:18125 8是符號位) 80000683 (實際數據id2:1667 8是符號位) 實際上就是31個字節 那么我們很容易計算出來如果滿存儲行大約(16*1024-128(塊頭塊尾部))/31 = 524 行數據。當然實際上存儲達不到這個值受到 B+樹分裂行為以及填充因子等限制實際上到不了這個值,我這里去大約500行數據 好了對于這張表這里我們可以實際大約計算一下理論值,實際值將略。 一層B+樹 最大16K空間 約500行數據 二層B+樹 最大約18M空間((16*1024-128)/14 * 16/1024 ) 約58000行數據((16*1024-128)/14 *500) 三層B+樹 最大約21000M空間(power((16*1024-130)/14,2) * 16/1024) 約673960500行數據(power((16*1024-130)/14,2) * 500) 四層B+樹 最大約24452000M空間(power((16*1024-130)/14,3) * 16/1024) 約782468140500行數據(power((16*1024-130)/14,3) * 500) 但是要注意這里最大空間受到主鍵選擇影響很大,如果不是int為主鍵那么其非葉子結點一行數據將不會是14字節如果是long類型將是18字節,那么最大空間 將不會達到這么大,而行數更是受到實際一行數據大小限制,這里只是以文章開頭建立的表為列子。 |
免責聲明:本站部分文章和圖片均來自用戶投稿和網絡收集,旨在傳播知識,文章和圖片版權歸原作者及原出處所有,僅供學習與參考,請勿用于商業用途,如果損害了您的權利,請聯系我們及時修正或刪除。謝謝!
始終以前瞻性的眼光聚焦站長、創業、互聯網等領域,為您提供最新最全的互聯網資訊,幫助站長轉型升級,為互聯網創業者提供更加優質的創業信息和品牌營銷服務,與站長一起進步!讓互聯網創業者不再孤獨!
掃一掃,關注站長網微信