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


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"'。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值