了解数据存储空间占用,可以更方便我们再企业中对于数据库相关优化做评估。
一、查看当前数据表空间占用信息
CREATE TABLE `project` (
`tenantsid` bigint(20) NOT NULL DEFAULT '0' COMMENT '租户ID',
`project_id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键',
`code` bigint(20) NOT NULL DEFAULT '0' COMMENT '项目编号',
`name` varchar(72) COLLATE utf8_bin DEFAULT '' COMMENT '项目名称',
PRIMARY KEY (`project_id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=59840 DEFAULT CHARSET=utf8 COLLATE=utf8_bin COMMENT='项目档'
1、通过iinformation_schema.tables查看数据空间占用信息
select table_name,data_length,index_length from information_schema.tables where table_name = 'project';
按照官网介绍:
DATA_LENGTH
对于MyISAM
,DATA_LENGTH
是数据文件的长度,以字节为单位。
对于InnoDB
,DATA_LENGTH
是为聚集索引分配的大约空间量(以字节为单位)。具体来说,它是聚集索引大小(以页为单位)乘以InnoDB
页大小。
INDEX_LENGTH
对于MyISAM
,INDEX_LENGTH
是索引文件的长度,以字节为单位。
对于InnoDB
,INDEX_LENGTH
是为非聚集索引分配的大约空间量(以字节为单位)。具体来说,它是非聚集索引大小的总和(以页为单位)乘以 InnoDB
页大小。
DATA_LENGTH = 聚集索引大小(以页为单位)乘以InnoDB
页大小
INDEX_LENGTH = 非聚集索引大小(以页为单位)乘以InnoDB
页大小
show status like '%page_size%';
innodb_space -s ibdata1 -T firestation/project space-indexes
可以看到这里面PRIMARY一共分配了97个page页占用空间 = 97*16*1024 = 1,589,248可以看到正好是DATA_LENGTH大小
前面也说到了当97个表只是当前project真实数据占用的空间大小,对于表来说,还存在其他的的空间占用,比如缓存、元数据等等,所以DATA_LENTGTH表示的只是真实数据的大小。当然对于日常的空间占用评估是足够了。
innodb_space -s ibdata1 -T firestation/project space-page-type-summary
可以看到project实际存储时使用到了704个page页,所以理论上应该占用空间704*16*1024=11,534,336
其实mysql在information_schema中提供了innodb系列的元数据表,它记录了innodb底层存储时真实的元数据信息,例如information_schema.innnodb_sys_tablespace(我这里是mysql5.7不同版本的名称不同,看官网说明)中就可以查看表真实存储空间大小。
select * from information_schema.innodb_sys_tablespaces where name = 'firestation/project';
可以看到这里的File_size就是上面通过真实数据page数计算出来的结果。
所以结论:
1、可以通过information_schema.table查看DATA_LENGTH,这个为当前主键索引也就是真实数据的空间占用大小。
2、可以通过information_schema.innodb_sys_tablespace 查看File_size,这个为当前project总占用空间大小
二、每行数据占用空间
其实通过上述的结论,就可以大致的评估出每行数据空间占用大小,总大小/行数,这里我们更深入了解下一行数据怎么计算的空间占用大小。
1、查看每一行数据占用空间大小
(1)首先先确定project存储tree一共为几层 , 这里先介绍一种查看到方式,后续在介绍另一种。
这里可以看到PRIMARY索引一共分2层,第1层非叶子节点只有一个page,第2层叶子节点共95个page页,需要注意的是这里叶子节点为0层,依次往上推。
innodb_space -s ibdata1 -T firestation/project -I PRIMARY -l 1 index-level-summary
page: page页编号,这里为3,也就是上面看到的root节点page编号
level:当前page所处的层级
data:当前page占用空间大小
free:当前page空闲空间大小,因为page大小固定16kg,所以就会存在页用不满的现象
recoreds:当前page存储的数据行数,这里因为是非叶子节点,所以指的是主键行数。
从这里就可以看出来,大约每行数据占用15000/250 = 60字节空间
行空间占用和字段数据有密切的关系,如果字段占用空间小(比如字段栏位少,无长文本字段等)那page可以存储更多的行数,整体的占用空间小,B+树层级少,查询速度快。
innodb_space -s ibdata1 -T firestation/project -p 5 page-illustrate
这张图就是展示了PAGE一个详细的空间结构,前面文章也介绍过,这里不再赘述。
可以看到Record Header + Record Data 是真实数据产生的空间占用 = 1631+13471 =15102也是验证了上面看到的page空间占用。
三、每行数据空间评估
根据上面的数据结果,选择一个project_id = 33819的一行数据,从空间上来看为15102字节/233 =64字节
当前行数据:
我们知道bigint占用8字节,varchar是不定长,一个汉字3字节。按照这样的算法
空间:8+8+8+12 = 36字节,远小于60字节,这是为什么呢?
这个就是需要了解行格式知识相关了:【Mysql】 InnoDB引擎深入- 行格式_mysql 5.6 innodb引擎 不支持行格式为:dynamic_Survivor001的博客-CSDN博客
根据行格式的知识,我们知道一行数据除了真实的数据之外还会记录一些额外的信息。
- 在这里以project_id =33819数据大致计算下
- 存在变长字段,且长度<255,则需要1个字节记录其长度(这里共1~2字节,记录最大值65535,所以这就是为什么一行数据不能超过这个阈值)
- 记录头5个字节
- 除此之外,数据里面处理记录真实数据外还记录其他内比如row_id(6字节),回滚指针(7字节)、事务id(6字节)
- 总计:1+5+7+6+6= 25(字节)
- 所以:真实数据36 + 25 ~= 60字节, 这样一看就差不多了。
- 总结:
- 一行数据一般来说差不多占用空间 = 25字节 + 字段栏位真实占用空间,当然如果一行数据存在大数据内容,可能一行数据就超过了page大小,就可能跨页,这个时候就会行溢出。需要更多的页来记录其内容,次数就会占用更多的空间,因为page本身也会有额外的空间占用。所以这就是为什么大数据栏位建议独立出来不要和普通字段放在一起,而text、blog有独立BLOB PAGE原因。
- 行溢出:【Mysql】 InnoDB引擎深入- 行溢出_innodb行溢出-CSDN博客
原文地址:https://blog.csdn.net/qq_31142237/article/details/134754180
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.7code.cn/show_46688.html
如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱:suwngjj01@126.com进行投诉反馈,一经查实,立即删除!