[MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键

标签: 数据库 FAQ InnoDB MySQL MySQL FAQ | 发表时间:2014-09-14 16:45 | 作者:yejr
出处:http://imysql.com

我们先了解下InnoDB引擎表的一些关键特征:

  • InnoDB引擎表是基于B+树的索引组织表(IOT);
  • 每个表都需要有一个聚集索引(clustered index);
  • 所有的行记录都存储在B+树的叶子节点(leaf pages of the tree);
  • 基于聚集索引的增、删、改、查的效率相对是最高的;
  • 如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择器作为聚集索引;
  • 如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引;
  • 如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。

综上总结,如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的,也就是下面这几种情况的存取效率最高:

  • 使用自增列(INT/BIGINT类型)做主键,这时候写入顺序是自增的,和B+数叶子节点分裂顺序一致;
  • 该表不指定自增列做主键,同时也没有可以被选为主键的唯一索引(上面的条件),这时候InnoDB会选择内置的ROWID作为主键,写入顺序和ROWID增长顺序一致;
  • 除此以外,如果一个InnoDB表又没有显示主键,又有可以被选择为主键的唯一索引,但该唯一索引可能不是递增关系时(例如字符串、UUID、多字段联合唯一索引的情况),该表的存取效率就会比较差。

实际情况是如何呢?经过简单 TPCC基准测试,修改为使用自增列作为主键与原始表结构分别进行TPCC测试,前者的TpmC结果比后者高9%倍,足见使用自增列做InnoDB表主键的明显好处,其他更多不同场景下使用自增列的性能提升可以自行对比测试下。

附图:

1、B+树典型结构

B+tree

2、InnoDB主键逻辑结构

Innodb-primary-key

 

延伸阅读:

1、 TPCC-MySQL使用手册

2、 B+Tree index structures in InnoDB

3、 B+Tree Indexes and InnoDB – Percona

4、 MySQL官方手册: Clustered and Secondary Indexes

相关 [mysql faq 系列] 推荐:

[MySQL FAQ]系列 -- mysqldump选项之skip-opt

- - MySQL 中文网
最近在用mysqldump备份时,想要把数据表和数据分开备份,因此做了2次备份. 执行备份数据库表结构时,指定了 --skip-opt 选项,相当于:. 选项 --create-option 看起来比较不起眼:. 事实上,如果把它disable的话,备份出来的表结构,会少了:. 等MySQL特有的数据表属性,需要注意下.

[MySQL FAQ]系列 -- 几种常见MySQL无法启动案例

- - MySQL 中文网
昨天在群里看到有新同学还在问MySQL无法启动的问题,于是总结了几个常见情况,权当普及帖了,老鸟自觉飞过. 问题1:目录、文件权限设置不正确. MySQL的$datadir目录,及其下属目录、文件权限属性设置不正确,导致MySQL无法正常读写文件,无法启动. 已有其他mysqld实例启动,且占用了相同端口,需要修改 port 选项.

[MySQL FAQ]系列 — MySQL复制中slave延迟监控

- - MySQL中文网
在MySQL复制环境中,我们通常只根据 Seconds_Behind_Master 的值来判断SLAVE的延迟. 这么做大部分情况下尚可接受,但并不够准确,而应该考虑更多因素. 首先,我们先看下SLAVE的状态:. 可以看到 Seconds_Behind_Master 的值是 3296,也就是SLAVE至少延迟了 3296 秒.

[MySQL FAQ]系列 -- 新手必看:一步到位之InnoDB

- - MySQL 中文网 -
前言:MySQL发展到今天,InnoDB引擎已经作为绝对的主力,除了像大数据量分析等比较特殊领域需求外,它适用于众多场景. 然而,仍有不少开发者还在“执迷不悟”的使用MyISAM引擎,觉得对InnoDB无法把握好,还是MyISAM简单省事,还能支持快速COUNT(*). 本文是由于最近几天帮忙处理discuz论坛有感而发,希望能对广大开发者有帮助.

[MySQL FAQ]系列 — processlist中哪些状态要引起关注

- - MySQL中文网
插图来自网络并作简单加工,如果觉得不当还请及时告知 :). 一般而言,我们在processlist结果中如果经常能看到某些SQL的话,至少可以说明这些SQL的频率很高,通常需要对这些SQL进行进一步优化. 今天我们要说的是,在processlist中,看到哪些运行状态时要引起关注,主要有下面几个:.

[MySQL FAQ]系列 — 为什么要关闭query cache,如何关闭

- - MySQL中文网
备注:插图来自淘宝苏普的博客并保留水印,如果觉得不当还请及时告知 :). 写在前面:MySQL的query cache大部分情况下其实只是鸡肋而已,建议全面禁用. 当然了,或许在你的场景下还是挺好的,还能发挥作用,那就继续使用吧,把本文当做参考就好. 不过,可能有的人人为只需要把 query_cache_size 大小调整为 0 就可以了,可以忽略 query_cache_type 参数的值,反正它也是可以在线调整的.

[MySQL FAQ]系列 — profiling中要关注哪些信息

- - MySQL中文网
利用MySQL的PROFILE功能,我们可以很方便的查看一个SQL具体的执行代价是怎样的,尤其是可以分析它的最大瓶颈在哪里. 目前PROFILE功能可提供除了内存以外的其他资源消耗统计,例如CPU、I/O、CONTEXT、SWAP等. PROFILE功能只能在SESSION级别使用,还做不到像SQL Server那样可以全局开启,收集一段时间后再关闭,这点有待改进.

[MySQL FAQ]系列 — 为什么InnoDB表要建议用自增列做主键

- - MySQL中文网
我们先了解下InnoDB引擎表的一些关键特征:. InnoDB引擎表是基于B+树的索引组织表(IOT);. 每个表都需要有一个聚集索引(clustered index);. 所有的行记录都存储在B+树的叶子节点(leaf pages of the tree);. 基于聚集索引的增、删、改、查的效率相对是最高的;.

[MySQL FAQ]系列 — 线上环境到底要不要开启query cache

- - MySQL中文网
Query Cache(查询缓存,以下简称QC)存储SELECT语句及其产生的数据结果,特别适用于:频繁提交同一个语句,并且该表数据变化不是很频繁的场景,例如一些静态页面,或者页面中的某块不经常发生变化的信息. InnoDB Buffer Pool或者. MyISAM key buffer里读取结果.