MYSQL INNODB 如何计算B+树表的最大容量和行数

考虑表结构如下:
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字节,那么最大空间
将不会达到这么大,而行数更是受到实际一行数据大小限制,这里只是以文章开头建立的表为列子。

作者微信:

               

时间: 2024-09-25 05:49:35

MYSQL INNODB 如何计算B+树表的最大容量和行数的相关文章

mysql查询语句通过limit来限制查询的行数_Mysql

mysql查询语句,通过limit来限制查询的行数. 例如: select name from usertb where age > 20 limit 0, 1; //限制从第一条开始,显示1条 select name from usertb where age > 20 limit 1; //同上面的一个效果 select name from usertb where age > 20 limit 4, 1; //显示从第五条开始,显示1条

Nodejs使用mysql模块之获得更新和删除影响的行数的方法

 业余时间玩nodejs的时候遇到点蛋疼的情况, 在使用mysql模块连接mysql操作, 想在update, delete语句的时候, 想知道到底update, delete成功了没有 在mysql中直接进行这样的判断的方法是使用 row_count(), 这一条语句要紧跟着你执行的sql语句后面. 而Nodejs的i/o都是异步的于是这就产生了一个问题, 不太好判断 row_count()到底是哪句sql执行的结果. 粗略的扫了一眼文档, 文档中并没有描述这个问题. 本想函数嵌套来达到同步的

Nodejs使用mysql模块之获得更新和删除影响的行数的方法_javascript技巧

在mysql中直接进行这样的判断的方法是使用 row_count(), 这一条语句要紧跟着你执行的sql语句后面. 而Nodejs的i/o都是异步的于是这就产生了一个问题, 不太好判断 row_count()到底是哪句sql执行的结果. 粗略的扫了一眼文档, 文档中并没有描述这个问题. 本想函数嵌套来达到同步的效果的, 却无意发现在执行sql对应的异步函数中的参数中有  affectedRows字段, 经测试, 这货就是 row_count()的结果.实例: 复制代码 代码如下: var cmd

MySQL InnoDB 共享表空间和独立表空间

MySQL  InnoDB 共享表空间和独立表空间 官网:https://dev.mysql.com/doc/refman/5.6/en/innodb-multiple-tablespaces.html 前言:学习mysql的时候总是习惯性的和oracle数据库进行比较.在学习mysql InnoDB的存储结构的时候也免不了跟oracle进行比较.Oracle的数据存储有表空间.段.区.块.数据文件:mysql InnoDB的存储管理也类似,但是mysql增加了一个共享表空间和独立表空间的概念:

MYSQL InnoDB表锁

InnoDB锁问题 InnoDB与MyISAM的最大不同有两点:一是支持事务(TRANSACTION):二是采用了行级锁.行级锁与表级锁本来就有许多不同之处,另外,事务的引入也带来了一些新问题.下面我们先介绍一点背景知识,然后详细讨论InnoDB的锁问题. 2.并发事务处理带来的问题 相对于串行处理来说,并发事务处理能大大增加数据库资源的利用率,提高数据库系统的事务吞吐量,从而可以支持更多的用户.但并发事务处理也会带来一些问题,主要包括以下几种情况.      更新丢失(ost Update):

MySQL Innodb表导致死锁日志情况分析与归纳_Mysql

案例描述在定时脚本运行过程中,发现当备份表格的sql语句与删除该表部分数据的sql语句同时运行时,mysql会检测出死锁,并打印出日志.两个sql语句如下:(1)insert into backup_table select * from source_table(2)DELETE FROM source_table WHERE Id>5 AND titleWeight<32768 AND joinTime<'$daysago_1week'teamUser表的表结构如下:PRIMARY

MySQL Innodb数据库性能实践——合适的表记录数

在实际工作中,经常有同事问道:MySQL Innodb表记录数多大是合适的? 一般的理解肯定是表越大性能越低,但具体低多少呢,是缓慢下降还是急剧下降,是1000万就下降还是1亿才下降呢? 针对这些问题,我做了一下基准测试,基准测试环境如下: [硬件配置] 硬件 配置 CPU Intel(R) Xeon(R) CPU E5620 主频2.40GHz, 物理CPU 2个,逻辑CPU 16个 内存 24G(6块 * 4G  DDR3 1333 REG) 硬盘 300G * 3个,SAS硬盘 15000

RDS for MySQL InnoDB 表级锁等待

RDS for MySQL InnoDB 表级锁等待   1. 显式 lock table 2. 隐式 lock table 在 RDS MySQL 实例日常使用中,有些情况下会发现出现 InnoDB 表级锁等待的情况,下面列出常见的2个原因.  1. 显式 lock table 执行了 lock tables tab_name read; 导致 DML 会话等待在表的表级锁上. 会话 1 lock tables tab_name read; 会话 2 会话 3   2. 隐式 lock tab

mysql innodb整理表空间 DATA_FREE值为啥不减小?

问题描述 mysql innodb整理表空间 DATA_FREE值为啥不减小? mysql5.5 innodb进行表空间的整理 ALTER TABLE fee_sum_day_provice ENGINE=InnoDB 整理完成后查询下表的DATA_FREE 发现没有减小和整理之前一样 为啥呢 ALTER TABLE不咋好使呢?