(转)mysql中InnoDB表为什么要建议用自增列做主键
InnoDB引擎表的特点
1、InnoDB引擎表是基于B+树的索引组织表(IOT)
关于B+树
(图片来源于网上)
B+ 树的特点:
(1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是有序的;
(2)不可能在非叶子结点命中;
(3)非叶子结点相当于是叶子结点的索引(稀疏索引),叶子结点相当于是存储(关键字)数据的数据层;
2、如果我们定义了主键(PRIMARY KEY),那么InnoDB会选择主键作为聚集索引、如果没有显式定义主键,则InnoDB会选择第一个不包含有NULL值的唯一索引作为主键索引、如果也没有这样的唯一索引,则InnoDB会选择内置6字节长的ROWID作为隐含的聚集索引(ROWID随着行记录的写入而主键递增,这个ROWID不像ORACLE的ROWID那样可引用,是隐含的)。
3、数据记录本身被存于主索引(一颗B+Tree)的叶子节点上。这就要求同一个叶子节点内(大小为一个内存页或磁盘页)的各条数据记录按主键顺序存放,因此每当有一条新的记录插入时,MySQL会根据其主键将其插入适当的节点和位置,如果页面达到装载因子(InnoDB默认为15/16),则开辟一个新的页(节点)
4、如果表使用自增主键,那么每次插入新的记录,记录就会顺序添加到当前索引节点的后续位置,当一页写满,就会自动开辟一个新的页
5、如果使用非自增主键(如果身份证号或学号等),由于每次插入主键的值近似于随机,因此每次新纪录都要被插到现有索引页得中间某个位置,此时MySQL不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多开销,同时频繁的移动、分页操作造成了大量的碎片,得到了不够紧凑的索引结构,后续不得不通过OPTIMIZE TABLE来重建表并优化填充页面。
综上总结,如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的,也就是下面这几种情况的存取效率最高:
1、使用自增列(INT/BIGINT类型)做主键,这时候写入顺序是自增的,和B+数叶子节点分裂顺序一致;
2、该表不指定自增列做主键,同时也没有可以被选为主键的唯一索引(上面的条件),这时候InnoDB会选择内置的ROWID作为主键,写入顺序和ROWID增长顺序一致;
除此以外,如果一个InnoDB表又没有显示主键,又有可以被选择为主键的唯一索引,但该唯一索引可能不是递增关系时(例如字符串、UUID、多字段联合唯一索引的情况),该表的存取效率就会比较差。
《高性能MySQL》中的原话
转载于:https://www.cnblogs.com/zuge/p/6092698.html
(转)mysql中InnoDB表为什么要建议用自增列做主键相关推荐
- 为什么要建议用自增列做主键
第一部分 InnoDB引擎表的特点 1.InnoDB引擎表是基于B+树的索引组织表(IOT) 关于B+树 B+ 树的特点: (1)所有关键字都出现在叶子结点的链表中(稠密索引),且链表中的关键字恰好是 ...
- MySQL中InnoDB
MySQL中有很多存储引擎,MyISAM.InnoDB.BDB(支持事务).MEMORY(存储在内存中).MERGE.NDB Cluster.ARCHIEVE.CSV.BLACKHOLE.FEDERA ...
- MySQL中Innodb的索引
如果想在一本书中找到某个特定主题,一般会先看输的"索引",找到对应的页码.在MySQL中,存储引擎用类似的方法使用索引,其先在索引中找到对应值,然后根据匹配的索引记录 ...
- MySQL中InnoDB引擎对索引的扩展
摘要:InnoDB引擎对索引的扩展,自动追加主键值及其对执行计划的影响. MySQL中,使用InnoDB引擎的每个表,创建的普通索引(即非主键索引),都会同时保存主键的值. 比如语句 CREATE T ...
- MySQL中Innodb的聚簇索引和非聚簇索引
聚簇索引 数据库表的索引从数据存储方式上可以分为聚簇索引和非聚簇索引(又叫二级索引)两种.Innodb的聚簇索引在同一个B-Tree中保存了索引列和具体的数据,在聚簇索引中,实际的数据保存在叶子页中, ...
- mysql中修改表的还原命令_MySQL的增、删、改、查和备份、恢复的命令
一.增删改查 1.创建数据库 CREATE DATABASE DBname mysqladmin-u root-p create DBname 2.删除数据库 DROP DATABASE DBname ...
- Mysql中Innodb大量插入数据时SQL语句的优化
innodb优化后,29小时入库1300万条数据 参考:http://blog.51yip.com/mysql/1369.html 对于Myisam类型的表,可以通过以下方式快速的导入大量的数据: A ...
- mysql中innodb的工作原理_解读MySQL的InnoDB引擎日志工作原理
当你使用UPDATE, INSERT, DELETE语句更新数据的时候,你就改变了两个地方的数据:log buffer和data buffers.Buffers是固定长度的内存块,通常是512字节. ...
- 一天一篇mysql之十二:mysql中group by的使用建议
一.建议使用一个索引来满足Order By子句. 在条件允许的情况下,笔者建议最好使用一个索引来满足Order By子句.如此的话,就可以避免额外的排序工作.这里笔者需要强调的一点是及时Order B ...
- mysql中Innodb简介
1.myql默认的存储引擎是Innodb,数据库读取和操作数据都是通过存储引擎进行的. 2.Innodb为了避免从磁盘读取数据过多,将存储数据在磁盘和内存中通过页为单位进行交互,一个页默认16kb,一 ...
最新文章
- VC++调试技巧学习总结
- eclipse插件egit安装使用
- python中变量名存储在哪里_python – 如何在内部存储和映射变量名称?
- redis memcache 性能比较
- 3d打印英语文献_锐医学院 | 只需10分钟!解读康复医学文献+英语学习
- 软件公司怎么定价它们的项目_如何为副项目定价
- 如何在多个SQL Server上执行作业
- osea/Beat Classification 4.0-4.2
- 一文弄懂LogSumExp技巧
- go语言ATM小案例
- 【Qt编程】基于Qt的词典开发系列二--本地词典的设计
- 音频特征----频谱图
- Java将字符串中的中文数字转化成阿拉伯数字或阿拉伯数字转化成中文数字
- php 开源项目汇总
- 拖拉机服务器不稳定,手扶拖拉机机油指示不稳定现象分析
- 软件版权申请流程有哪些
- 深入理解Activity的生命周期
- PHP网站漏洞poc,phpyun某处SQL注入漏洞含POC
- matlab plotroc 画roc曲线
- 【图论】计蒜客商汤在线编程挑战赛 D题 白色相簿
热门文章
- 如何使一个你没有源代码的DLL文件变为强命名的DLL
- Perl面向对象编程
- HDU 4296 building
- 全部选中替换_一键解锁查找替换的新玩法!
- java redis 哨兵_突破Java面试(23-7) - Redis的哨兵架构
- linux shell 多个命令一起执行的几种方法
- java web 调度_javaweb车辆调度信息管理平台
- 商城系统使用redis做什么_B2B2C商城系统与B2C商城系统有什么区别呢?企业该如何选择?...
- 【图文教程】Windows给Rabbitmq安装rabbitmq_delayed_meaage_exchange
- 6.3交换器(Exchangers)