为什么MySQL索引要用B+树,而不是B树?
一个面试题:InnoDB 一棵 B+ 树可以存放多少行数据?这个问题的简单回答是:约 2 千万。
InnoDB 的所有数据文件(后缀为 ibd 的文件),他的大小始终都是 16384(16K)的整数倍。
磁盘扇区、文件系统、InnoDB 存储引擎都有各自的最小存储单元。
mysql> show variables like 'innodb_page_size';
+------------------+-------+
| Variable_name | Value |
+------------------+-------+
| innodb_page_size | 16384 |
+------------------+-------+
1 row in set (0.00 sec)
数据表中的数据都是存储在页中的,所以一个页中能存储多少行数据呢?假设一行数据的大小是 1K,那么一个页可以存放 16 行这样的数据。
所以人们想了一个办法,用 B+ 树的方式组织这些数据,如下图所示:
现在来看下,要查找一条数据,怎么查?如:
select * from user where id=5;
5 zhao2 27
InnoDB 存储引擎的最小存储单元是页,页可以用于存放数据也可以用于存放键值+指针,在 B+ 树中叶子节点存放数据,非叶子节点存放键值+指针。
索引组织表通过非叶子节点的二分查找法以及指针确定数据在哪个页中,进而在去数据页中查找到需要的数据。
怎么得到 InnoDB 主键索引 B+ 树的高度?
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;
下面我们对数据库表空间文件做想相关的解析:
因此我们想要的 page level 的值在整个文件中的偏移量为:16384*3+64=49152+64=49216,前 2 个字节中。
linetem 表的 page level 为 2,B+ 树高度为page level+1=3。
region 表的 page level 为 0,B+ 树高度为 page level+1=1。
customer 表的 page level 为 2,B+ 树高度为 page level+1=3。
这三张表的数据量如下:
总结
作者:李平
简介:目前在一家 O2O 互联网公司从事设计、开发工作。业余时间喜欢跑步、看书、游戏。喜欢简单而高效的工作环境,熟悉 JavaEE、SOA、数据库架构、优化、系统运维,有大型门户网站,金融系统建设经验。RHCE、MySQL OCP。MyCAT 开源项目成员。
编辑:陶家龙、孙淑娟
出处:https://www.cnblogs.com/leefreeman/p/8315844.html
精彩文章推荐:
- 数据库索引的实现为什么用B+树而不用B树
- B树和B+树对比,为什么MySQL数据库索引选择使用B+树?
- 为什么MongoDB采用B树索引,而Mysql用B+树做索引
- OpenMp并行提升时间为什么不是线性的?
- 为什么说没有大数据的人工智能什么都不是?
- 从B树、B+树、B*树谈到R 树
- java socket 实际端口为什么不是自定的端口
- 为什么经理、总监多是空降, 而不是从内部提拔?
- JDBC为什么要使用PreparedStatement而不是Statement
- 不是要知道怎样做,而是要知道为什么这么做
- 关于B树 、B+树、B*树
- 为什么API多用C而不是C++,为什么C++程序大多不使用异常
- TCP 为什么是三次握手,为什么不是两次或四次?
- Mysql为什么企业一般使用InnoDB引擎而不是使用效率更高的MyISAM引擎?
- 【经典数据结构】B树与B+树(转)
- 为什么大多数大型网站不是用Java写的
- 【补充】为什么初始化SDRAM中 adrl r2, mem_cfg_val而不是 ldr r2,=mem_cfg_val
- 为什么我希望用C而不是C++来实现ZeroMQ
- 为什么要使用slf4j而不是log4j
- JDBC为什么要使用PreparedStatement而不是Statement