mysql 数据 行宽_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

0000c04000 0200 00 00 00 00 00 0085

查看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=341490301DEFAULT CHARSET=utf8

1 row in set (0.00 sec)

[root@db001 db1]# hexdump -C -s 49216 -n 10 page.ibd

0000c04000 0300 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"'。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值