innodb行宽几百字节 ,千万行记录,索引深度多少?

本文涉及的产品
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 高可用系列,价值2615元额度,1个月
简介: mysql并没有提供查看索引高度的视图,所以过程比较麻烦。

root@localhost:mysql3307.sock [db1] 11:30:05> show create table page\G
*************************** 1. row ***************************
Table: page
Create Table: CREATE TABLE `page` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`text` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=11831127 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)


root@localhost:mysql3307.sock [db1] 11:28:46> select count(*) from page;
+----------+
| count(*) |
+----------+
| 11831126 |
+----------+
1 row in set (1.95 sec)


查看平均行大小
root@localhost:mysql3307.sock [db1] 11:27:35> show table status like 'page'\G
*************************** 1. row ***************************
Name: page
Engine: InnoDB
Version: 10
Row_format: Dynamic
Rows: 11822697
Avg_row_length: 394
Data_length: 4661968896
Max_data_length: 0
Index_length: 0
Data_free: 5242880
Auto_increment: 11831127
Create_time: 2018-08-25 11:23:11
Update_time: 2018-08-25 11:27:12
Check_time: NULL
Collation: utf8_general_ci
Checksum: NULL
Create_options:
Comment:
1 row in set (0.00 sec)



root@localhost:mysql3307.sock [db1] 11:28:38> select * from mysql.innodb_index_stats where table_name='page';
+---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
| database_name | table_name | index_name | last_update | stat_name | stat_value | sample_size | stat_description |
+---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
| db1 | page | PRIMARY | 2018-08-25 11:28:12 | n_diff_pfx01 | 12172354 | 20 | id |
| db1 | page | PRIMARY | 2018-08-25 11:28:12 | n_leaf_pages | 251755 | NULL | Number of leaf pages in the index |
| db1 | page | PRIMARY | 2018-08-25 11:28:12 | size | 288128 | NULL | Number of pages in the index |
+---------------+------------+------------+---------------------+--------------+------------+-------------+-----------------------------------+
3 rows in set (0.00 sec)

root@localhost:mysql3307.sock [db1] 11:31:23> select * from mysql.innodb_table_stats where table_name='page';
+---------------+------------+---------------------+----------+----------------------+--------------------------+
| database_name | table_name | last_update | n_rows | clustered_index_size | sum_of_other_index_sizes |
+---------------+------------+---------------------+----------+----------------------+--------------------------+
| db1 | page | 2018-08-25 11:28:12 | 12172354 | 288128 | 0 |
+---------------+------------+---------------------+----------+----------------------+--------------------------+

平均一页多少记录?
root@localhost:mysql3307.sock [db1] 11:32:33> select 11831126/288128;
+-----------------+
| 11831126/288128 |
+-----------------+
| 41.0620 |
+-----------------+
1 row in set (0.00 sec)

查看索引高度



InnoDB是索引组织表,每个页都包含一个PAGE_LEVEL的信息,用于表示当前页所在索引中的高度。默认叶子节点的高度为0,那么root页的PAGE_LEVEL + 1就是这棵索引的高度。在第三个页 FIL_PAGE_INODE 索引页,这个索引页是聚集索引的root,Root页的位置通常是不会更改的, 接下去的问题就是怎样得到一张表所有索引的Root页所在的位置呢?

root@localhost:mysql3307.sock [db1] 11:51:29> 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 b.name='db1/page';
+----------+---------+----------+------+-------+---------+
| name | name | index_id | type | space | PAGE_NO |
+----------+---------+----------+------+-------+---------+
| db1/page | PRIMARY | 133 | 3 | 100 | 3 |
+----------+---------+----------+------+-------+---------+
1 row in set (0.00 sec)

root@localhost:mysql3307.sock [db1] 11:55:26> show variables like '%innodb_page%';
+----------------------+-------+
| Variable_name | Value |
+----------------------+-------+
| innodb_page_cleaners | 4 |
| innodb_page_size | 16384 |
+----------------------+-------+
2 rows in set (0.00 sec)


有了这些信息就可以方便的定位啦,因为PAGE_LEVEL在每个页的偏移量64位置出,占用两个字节,通过hexdump这样的工具就可以快速定位到所需要的树高度信息:
[root@db001 db1]# hexdump -C -s 49216 -n 10 page.ibd
0000c040 00 02 00 00 00 00 00 00 00 85

查看page表,49216表示的是3*16384+64,即第3个页偏移量64位置开始读取10个字节,但不是读取2个字节就可以了嘛?其实因为后面8个字节对应的是index_id,这里index_id是 00 85 即133, PAGE_LEVEL为0002,那么索引的高度就为 3


继续插入记录到 3亿 多记录时候索引高度变成 4
root@localhost:mysql3307.sock [db1] 14:00:31> show create table page\G
*************************** 1. row ***************************
Table: page
Create Table: CREATE TABLE `page` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(100) DEFAULT NULL,
`text` varchar(100) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT= 341490301 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)

[root@db001 db1]# hexdump -C -s 49216 -n 10 page.ibd
0000c040 00 03 00 00 00 00 00 00 00 85

虽然通常来说索引树的高度为3~4层,但是极端情况下,比如数据量超级大,页比较小,如4K,那么高度也是可能破4的。

hexdump命令 一般用来查看“二进制”文件的十六进制编码,但实际上它能查看任何文件,而不只限于二进制文件。
语法
hexdump [选项] [文件]...
选项
-n length 只格式化输入文件的前length个字节。 -C 输出规范的十六进制和ASCII码。 -b 单字节八进制显示。 -c 单字节字符显示。 -d 双字节十进制显示。 -o 双字节八进制显示。 -x 双字节十六进制显示。 -s 从偏移量开始输出。 -e 指定格式字符串,格式字符串包含在一对单引号中,格式字符串形如:'a/b "format1" "format2"'。
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
目录
相关文章
|
7月前
|
存储 算法 关系型数据库
深入理解InnoDB索引数据结构和算法
1. **索引定义**:索引是提升查询速度的有序数据结构,帮助数据库系统快速找到数据。 2. **索引类型**:包括普通索引、唯一索引、主键索引、空间索引和全文索引,每种有特定应用场景。 3. **数据结构**:InnoDB使用B+树作为索引结构,确保所有节点按顺序排列,降低查询时的磁盘I/O。 4. **B+树特性**:所有数据都在叶子节点,非叶子节点仅存储索引,提供高效范围查询。 5. **索引优势**:通过减少查找数据所需的磁盘I/O次数,显著提高查询性能。 **总结:**InnoDB索引通过B+树结构,优化了数据访问,使得查询速度快,尤其适合大数据量的场景。
395 0
深入理解InnoDB索引数据结构和算法
|
7月前
|
存储 关系型数据库 MySQL
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
索引大战:探秘InnoDB数据库中B树和Hash索引的优劣
69 0
|
17天前
|
存储 算法 关系型数据库
InnoDB与MyISAM实现索引方式的区别
InnoDB和MyISAM均采用B+树索引,但在实现上有所不同。InnoDB的主键索引在叶子节点存储完整数据记录,辅助索引则存储主键值;而MyISAM的主键索引与数据文件分离,仅存数据地址,且主辅索引无区别,支持非唯一主索引。
36 1
|
7月前
|
存储 SQL 关系型数据库
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?
86 1
系统设计场景题—MySQL使用InnoDB,通过二级索引查第K大的数,时间复杂度是多少?
|
7月前
|
存储 算法 关系型数据库
InnoDb行格式、数据页结构、索引底层原理和如何建立索引
InnoDb行格式、数据页结构、索引底层原理和如何建立索引
120 0
|
存储 关系型数据库 MySQL
6.2.2 【MySQL】InnoDB中的索引方案
6.2.2 【MySQL】InnoDB中的索引方案
86 0
|
存储 关系型数据库 MySQL
6.2.3 【MySQL】InnoDB的B+树索引的注意事项
6.2.3 【MySQL】InnoDB的B+树索引的注意事项
84 0
|
6月前
|
存储 关系型数据库 MySQL
MySQL数据库——InnoDB引擎-逻辑存储结构(表空间、段、区、页、行)
MySQL数据库——InnoDB引擎-逻辑存储结构(表空间、段、区、页、行)
127 7
|
6月前
|
存储 关系型数据库 MySQL
【MySQL技术内幕】5.1-InnoDB存储引擎索引概述
【MySQL技术内幕】5.1-InnoDB存储引擎索引概述
58 0
|
7月前
|
SQL 存储 关系型数据库
【深入浅出MySQL】「底层原理」InnoDB索引原理全程实操指南,带你从入门到精通
【深入浅出MySQL】「底层原理」InnoDB索引原理全程实操指南,带你从入门到精通
226 1