背景:
       用innodb_table_monitor来查看表内部的存储信息和索引结构是一个好的办法。再之前的MySQL 字符串主键和整型主键分析中提到了一些内容,但没有细讲,现在来好好的分析下。

使用方法:
       
建立一张 innodb_table_monitor的表:

create table innodb_table_monitor(a int)engine=innodb;

表建立之后,会每隔1m20s间隔把监控到的信息写到error日志中。要是停止监控的话,只需要删除表就可以了。注意:要是一直开启的话,错误日志会变的非常大。

日志的具体信息:

===========================================
121103 10:25:57 INNODB TABLE MONITOR OUTPUT
===========================================
--------------------------------------
TABLE: name SYS_FOREIGN, id 0 11, flags 0, columns 7, indexes 3, appr.rows 8
COLUMNS: ID: DATA_VARCHAR prtype 524292 len 0; FOR_NAME: DATA_VARCHAR prtype 524292 len 0; REF_NAME: DATA_VARCHAR prtype 524292 len 0; N_COLS: DATA_INT len 4; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
INDEX: name ID_IND, id 0 11, fields 1/6, uniq 1, type 3
root page 46, appr.key vals 8, leaf pages 1, size pages 1
FIELDS: ID DB_TRX_ID DB_ROLL_PTR FOR_NAME REF_NAME N_COLS
INDEX: name FOR_IND, id 0 12, fields 1/2, uniq 2, type 0
root page 47, appr.key vals 4, leaf pages 1, size pages 1
FIELDS: FOR_NAME ID
INDEX: name REF_IND, id 0 13, fields 1/2, uniq 2, type 0
root page 48, appr.key vals 3, leaf pages 1, size pages 1
FIELDS: REF_NAME ID
--------------------------------------
TABLE: name SYS_FOREIGN_COLS, id 0 12, flags 0, columns 7, indexes 1, appr.rows 8
COLUMNS: ID: DATA_VARCHAR prtype 524292 len 0; POS: DATA_INT len 4; FOR_COL_NAME: DATA_VARCHAR prtype 524292 len 0; REF_COL_NAME: DATA_VARCHAR prtype 524292 len 0; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
INDEX: name ID_IND, id 0 14, fields 2/6, uniq 2, type 3
root page 49, appr.key vals 8, leaf pages 1, size pages 1
FIELDS: ID POS DB_TRX_ID DB_ROLL_PTR FOR_COL_NAME REF_COL_NAME
--------------------------------------

上面显示,其中输出结构的开始部分会包含2张内部数据字典表用于维护外键的信息,表名为SYS_FOREIGN、SYS_FOREIGN_COLS。看看用户创建表的信息:

1,有主键的表(有数据):

CREATE TABLE `test` (
`uid` char(36) NOT NULL DEFAULT '',
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`uid`),
KEY `idx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
 1 TABLE: name test/test, id 0 718, flags 1, columns 7, indexes 2, appr.rows 635787
2 COLUMNS: uid: DATA_MYSQL DATA_NOT_NULL len 108; id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 765; status: DATA_INT DATA_BINARY_TYPE len 1; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
3 INDEX: name PRIMARY, id 0 1387, fields 1/6, uniq 1, type 3
4 root page 3, appr.key vals 635787, leaf pages 4056, size pages 4078
5 FIELDS: uid DB_TRX_ID DB_ROLL_PTR id name status /*主键包含所有列*/
 6 INDEX: name idx_id, id 0 1388, fields 1/2, uniq 2, type 0  
7 root page 4, appr.key vals 638241, leaf pages 1834, size pages 1896
8 FIELDS: id uid /*表中定义的二级索引包含主键uid列*/

第一部分(1):表信息:表名(test),表ID(718),列数(7),索引数(2),索性的基数<Cardinality>(625787,会变动);

第二部分(2):列信息:包括列名、列类型(DATA_XXXX)、是否NULL、以及列字段的长度。后面还有额外三列(主键ID,事务ID,回滚子指针) 总共7列;

• DATA_xxx(列类型): These symbols indicate the data type. There may be multiple DATA_xxx symbols for a given column.
• prtype(列的数据类型的字符集编码,空性,符号性,以及是否它是一个二进制字符串): The column's “precise” type. This field includes information such as the column data type, character set code, nullability,signedness, and whether it is a binary string. This field is described in the innobase/include/data0type.h source file.
• len(列字段的长度):The column length in bytes.
• prec(类型的精确值):The precision of the type.

第三部分(3~5):索引信息:索引名、索引ID,fields m/n (m代表用户定义索引中的列数/n代表总的索引列数,其中包含附加的internal columns),由于没有显示的定义主键或者非空的唯一索引,InnoDB会建表的时候自动的创建名字为GEN_CLUST_INDEX的Clustered Index。如果显示的定义一个主键的话,这个时候INDEX中name的值是:PRIMARY。以及 一些page信息和索引的基数信息。最后则是被索引的列,和 fields m/n 里的n对应。

• type(索引类型:聚集索引1,唯一索引2,普通索引0,既聚集又唯一3): The index type. This is a bit field. For example, 1 indicates a clustered index and 2 indicates a unique index, so a clustered index (which always contains unique values), will have a type value of 3. An index with a type value of 0 is neither clustered nor unique. The flag values are defined in the innobase/include/dict0mem.h source file.
• root page(索引节点:根节点): The index root page number.
• appr. key vals(索引的基数): The approximate index cardinality.
• leaf page(页节点大小): number of leaf pages in the index.
• size pages(总页大小): The approximages: The approate total number of pages in the index.
• FIELDS(被索引的列,主键包含所有列以及隐藏列,二级索引包含主键): The names of the fields in the index. For a clustered index that was generated automatically, the field list begins with the internal DB_ROW_ID (row ID) field. DB_TRX_ID and DB_ROLL_PTR are always added internally to the clustered index, following the fields that comprise the primary key. For a secondary index, the final fields are those from the primary key that are not part of the secondary index.

2,上面的表是有主键的,看看无主键的表(没有数据):

CREATE TABLE `test1` (
`uid` char(36) NOT NULL DEFAULT '',
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
KEY `idx_id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8
1 TABLE: name test/test1, id 0 820, flags 1, columns 7, indexes 2, appr.rows 0
2 COLUMNS: uid: DATA_MYSQL DATA_NOT_NULL len 108; id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 765; status: DATA_INT DATA_BINARY_TYPE len 1; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
3 INDEX: name GEN_CLUST_INDEX, id 0 1524, fields 0/7, uniq 1, type 1 /*1 说明只是主键,不是唯一*/
4 root page 3, appr.key vals 0, leaf pages 1, size pages 1
5 FIELDS: DB_ROW_ID DB_TRX_ID DB_ROLL_PTR uid id name status
6 INDEX: name idx_id, id 0 1525, fields 1/2, uniq 2, type 0
7 root page 4, appr.key vals 0, leaf pages 1, size pages 1
8 FIELDS: id DB_ROW_ID

1和2对比异同:
      第一行和第二行他们的信息是一样的。
      第三行出现不一致,因为1的表是有主键的,而2的表没有主键,2会自动生成一个Row_ID来代替,而导致第五行也不一致,因为2比1多了一个Row_ID(6个字节)。所以2的表中被索引的列有7个,而1只有6个,2没有定义索引列,而1定义了一个(fields)。因为二级索引包含主键列(第8行),主键不一样了,导致二级索引的列也会不一样。

3,测试有没有主键表大小问题:

CREATE TABLE `test2` (
`uid` char(36) NOT NULL DEFAULT '',
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
PRIMARY KEY `idx_id` (`id`)
) ENGINE=InnoDB; /*有自增主键*/ CREATE TABLE `test3` (
`uid` char(36) NOT NULL DEFAULT '',
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL
) ENGINE=InnoDB; /*无主键*/ CREATE TABLE `test4` (
`uid` char(36) NOT NULL DEFAULT '',
`id` int(11) NOT NULL,
`name` varchar(255) DEFAULT NULL,
`status` tinyint(4) DEFAULT NULL,
PRIMARY KEY (`uid`)
) ENGINE=InnoDB; /*有字符串主键*/
--------------------------------------
TABLE: name test/test2, id 0 824, flags 1, columns 7, indexes 1, appr.rows 625647
COLUMNS: uid: DATA_MYSQL DATA_NOT_NULL len 108; id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 765; status: DATA_INT DATA_BINARY_TYPE len 1; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
INDEX: name PRIMARY, id 0 1532, fields 1/6, uniq 1, type 3
root page 3, appr.key vals 625647, leaf pages 4056, size pages 4070
FIELDS: id DB_TRX_ID DB_ROLL_PTR uid name status
--------------------------------------
TABLE: name test/test3, id 0 825, flags 1, columns 7, indexes 1, appr.rows 617020
COLUMNS: uid: DATA_MYSQL DATA_NOT_NULL len 108; id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 765; status: DATA_INT DATA_BINARY_TYPE len 1; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
INDEX: name GEN_CLUST_INDEX, id 0 1533, fields 0/7, uniq 1, type 1
root page 3, appr.key vals 617020, leaf pages 4311, size pages 4326
FIELDS: DB_ROW_ID DB_TRX_ID DB_ROLL_PTR uid id name status
--------------------------------------
TABLE: name test/test4, id 0 826, flags 1, columns 7, indexes 1, appr.rows 655560
COLUMNS: uid: DATA_MYSQL DATA_NOT_NULL len 108; id: DATA_INT DATA_BINARY_TYPE DATA_NOT_NULL len 4; name: DATA_VARMYSQL len 765; status: DATA_INT DATA_BINARY_TYPE len 1; DB_ROW_ID: DATA_SYS prtype 256 len 6; DB_TRX_ID: DATA_SYS prtype 257 len 6; DB_ROLL_PTR: DATA_SYS prtype 258 len 7;
INDEX: name PRIMARY, id 0 1534, fields 1/6, uniq 1, type 3
root page 3, appr.key vals 655560, leaf pages 4056, size pages 4078
FIELDS: uid DB_TRX_ID DB_ROLL_PTR id name status
--------------------------------------

结果是:test2和test4大小一样,因为主键包含所有列。test3最大,因为每行都多了一个额外 row_id 列(6字节)。上面是针对表中只有主键进行测试的(比较特殊),要是有多个二级索引或则组合索引(常见),情况可能发生变化,特别是有随机字符串主键,原因请看这里

总结:

所以,从上面看出 innodb 都最好必须设置主键,而且是整型自增的。为什么不是字符串,请看这里。不设置主键没有任何好处:即使不设置主键也不会让表空间变小(除非主键需要新增列),反而使得插入更随机无序,可能导致IO更高。具体原因可以都通过innodb_table_monitor看出。

 

MySQL innodb_table_monitor 解析的更多相关文章

  1. MySQL Binlog 解析工具 Maxwell 详解

    maxwell 简介 Maxwell是一个能实时读取MySQL二进制日志binlog,并生成 JSON 格式的消息,作为生产者发送给 Kafka,Kinesis.RabbitMQ.Redis.Goog ...

  2. Mysql流程解析

    Mysql流程解析 流程图 流程图解析 客户端发送一条sql语句. 1.此时,mysql会检查sql语句,查看是否命中缓存,如果命中缓存,直接返回结果,不继续执行.没有命中则进入解析器. 2.解析器会 ...

  3. Mysql日志解析

    修改Mysql配置 Mysql配置地址为: C:\Program Files (x86)\MySQL\MySQL Server 5.5 如果无法修改可以把my.ini拷贝出来,修改完后,再拷贝回去! ...

  4. mysql binlog解析概要

    1,dump协议: 根据数据库的ip+port创建socket,如果创建成功,说明链接建立成功,接下来是使用dump协议订阅binlog 链接建立成功之后,服务端会主动向客户端发送如下问候信息gree ...

  5. Mysql 反向解析 导致远程访问慢

    在云端部署了mysql后,发现远程连接的响应速度非常慢(3-10s) 但是在本地访问数据库却没有问题 经过一番google这才知道原来mysql默认会进行反向解析,即通过ip地址反向向ISP申请获取域 ...

  6. MySQL Binlog解析

    https://yq.aliyun.com/articles/238364?spm=5176.8067842.tagmain.52.73PjU3 摘要: 概述 MySQL的安装可以参考:Linux(C ...

  7. mysql反向解析导致连接缓慢

    Content 0.序 1.问题 2.原因 3.解决办法 0.序 本文主要是记录Mysql安装在 VMWARE下,本地连接Mysql速度很慢的原因及解决办法. 1.问题 本地的一个网站使用mysql数 ...

  8. MySQL Binlog解析(2)

    一.TABLE_MAP_EVENT Used for row-based binary logging beginning with MySQL 5.1.5.The TABLE_MAP_EVENT d ...

  9. MySQL Binlog解析(1)

    一.Binlog File Binlog files start with a Binlog File Header followed by a series of Binlog Event Binl ...

随机推荐

  1. python抓取历年特码开奖记录

    背景: 小时候,有种游戏,两个主人公:白XX和曾XX,每个家庭把他俩像活菩萨一样供着,供他们吃,供他们穿 做生意的老板为了这两位活菩萨,关门大吉 农民为了这两位活菩萨卖牛卖田变卖家产 做官的为了这两位 ...

  2. 自学Python1.1-简介

    1.python语言介绍 python的创始人:Guido Van Rossum 2.python是一门什么样的语言 2.1  编程语言主要从以下几个角度进行分类:编译型,静态型,动态性,强类型定义语 ...

  3. [原创]mysql的zip包如何在windows下安装

    今天在尝试zipkin的链路数据写入mysql,本机恰好没有按照mysql.找到一个很久前谁发的mysql-5.6.19-winx64.zip,版本不新?别挑剔啦,只是本机测试,能用就好哈哈.. 解压 ...

  4. Asp.Net Web API(一)

    什么是Web API HTTP不仅仅服务于Web Pages.他也是一个创建展示服务和数据的API的强大平台.HTTP是简单的,灵活的,无处不在的.你能够想象到几乎任何的平台都会有HTTP服务库.HT ...

  5. 代码生成利器:IDEA 强大的 Live Templates(转)

    代码生成利器:IDEA 强大的 Live Templates - 文章 - 伯乐在线http://blog.jobbole.com/110607/ 前言 Java 开发过程经常需要编写有固定格式的代码 ...

  6. 框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解)

    框架原理第二讲,RTTI,运行时类型识别.(以MFC框架讲解) 一丶什么是RTTI,以及RTTI怎么设计 通过第一讲,我们知道了怎么样升成一个窗口了,以及简单的消息循环. 第二讲则是主要讲解RTTI ...

  7. 高性能管线式HTTP请求(实践·原理·实现)

      该篇实际是介绍pipe管线的原理,下面主要通过其高性能的测试实践,解析背后数据流量及原理.最后附带一个简单的实现     实践 先直接看对比测试方法 对于单一客户端对服务器进行http请求,一般我 ...

  8. bzoj 5016: [Snoi2017]一个简单的询问

    Description 给你一个长度为N的序列ai,1≤i≤N和q组询问,每组询问读入l1,r1,l2,r2,需输出 get(l,r,x)表示计算区间[l,r]中,数字x出现了多少次. Input 第 ...

  9. Hello 2018, Bye 2017

    2017年过去了,过去一年经历了太多,改变了好多好多,可以说人生进入了另一个阶段,有可能是成熟吧. 回顾2017 去年换了新工作,离开了将近工作了8年的公司,不带走一丝云彩,为其任劳任怨,最后没有任何 ...

  10. 防盗链与token运用

    为什么要防盗链? 例如手机/PC应用,如果有人知道你的api地址,和应用格式,那么他人就可以利用这个接口进行盗链:盗取/盗用里面的数据. 防盗链特性: 1.因为是非开放性的,所以所有的接口都是封闭的, ...