InnoDB的主键索引(Primary Key)是Cluster形式的(聚簇索引)。

InnoDB的非主键索引(Secondary Index)是普通的B+Tree索引。

两种索引在Root Node和Branch Node是一样的,在Leaf Node就不一样了。

Primary Key存放的是表的实际数据,不仅包含关键字段的数据,还包括其它字段的数据,整个数据以主键之有序排列。

Secondary Index存放索引键的相关信息,此外还有InnoDB的主键值(当移动行或数据页的分裂,这个策略降低了维护次索引的工作)。

所以InnoDB通过主键来访问数据效率是非常高的,而通过Secondary Index来访问的话要经过两步,从Secondary Index的Leaf Node获取主键值,再通过主键值检索一次。

MyISAM的主键索引和非主键索引的差别很小(区别是主键必须是唯一且非空的键)。

其存储结构和Secondary Index也基本相同,差别是Leaf Node存放索引键的相关信息外,存放能够直接定位到MyISAM数据文件中相应数据行的信息,而不是主键值。

MyISAM的数据布局相对简单,在硬盘上是按照插入的顺序来存储的。

下面从网上copy过来的示意图,一目了然^-^:

InnoDB中按照主键的顺序来插入行,如果不需要特殊的聚簇,定义一个代理键是个好注意(最简单的是AUTO_INCREMENT列),

这样保证数据插入保持着连续顺序并且对于使用主键连接会获得更好的性能。所以->

关于聚簇索引使用连续顺序的键是最好的场景:

最好避免使用随机的聚簇键。比如,从性能的角度来说,使用UUID是个不好的方法:它使聚簇索引的插入是随机的。这是最不好的场景了。并且对于数据的聚集也没有什么帮助;UUID作为主键的表不仅插入速度慢,而且索引还非常的大。一些原因是由于主键变大,而另一些原因不用怀疑的就是页的分裂和产生的一些碎片。

因为新行的主键并不是必须的比前一个主键值要大,因此InnoDB不能总是把新行放到这个索引之后。必须要为新行找到一个合适的位置-平均位置,也就是在靠近已存在数据的中部为新的数据生成一个空间。这就导致了一些额外的工作以及不理想的数据布局:

1.目标页要刷新到硬盘并且要清除缓存。InnoDB在插入新行之前,要找到它和从硬盘中读取它。这就导致了很多的随机IO。

2.InnoDB有的时候会分裂页,这样做的目的是为新行创建空间。这需要移动很多的数据。

因为页的分裂,页会变得稀疏并且不规则的填充。因此最终数据是碎片的。

在读取许多随机值到聚簇索引中之后,你应该使用OPTIMIZE TABLE语句重新构建表并且优化的填充页。

聚簇数据有很多重要的优势。

能使相关联的数据距离很近。比如,当要实现一个mailbox,你可以通过user_id来聚簇,因此你能通过获取硬盘上一小部分的页来获得一个单独用户的所有消息。如果你不做聚簇,那么每个消息可能都需要各自的硬盘I/O。

数据访问更加快速。一个聚簇索引在B-TREE上即保存了索引也保存了数据。因此从聚集索引获取行一般要快于在非聚集索引中比较查找。

使用覆盖索引的语句可以使用包含在叶子节点的主键值。

如果你设计表和语句的时候好好利用它们,对性能的提高大有帮助。然而聚簇索引也有很多缺点

聚簇会大幅提高IO限制(IO-BOUND)工作量。如果数据在内存中的顺序对数据的访问并不是什么问题的话,聚簇就不能带来那么多好处了。

插入的顺序影响插入的速度。按照主键的速度插入行是最快的读入数据到InnoDB表的方法。如果你没有依照主键的顺序来读取数据,那么在读取很多数据之后,使用OPTIMIZE TABLE来重新组织表是个很好的主意。

更新聚簇索引的列消耗是非常高的。因为它迫使InnoDB把每一行移动到新的位置。

当新的一行插入或行的主键更新,这样会导致聚簇索引的页的分裂。当一个行的键值决定了该行以及它所有的数据一定要放在一页里的时候,页的分裂就发生了。因为存储引擎必须把页分为两个来容纳这个行。页的分裂会导致表占用更多的空间。

聚簇的表会降低检索整张表的速度。尤其是在由于页的分裂,造成行没有被压缩或者没有连续的存储的情况下,问题就很严重。

非聚簇索引可能比你所想像的要大很多。因为它们的叶子节点包含了它们引用行的主键列。

非聚簇索引的访问需要两个索引的查找。

最后的一条可能有些困惑,为什么非聚簇索引需要两次索引的查找?答案就隐藏在非聚簇索引所存储的“行指针”上。记住一个叶子节点存储的指针并不是引用行的物理地址,而是存储了行的主键值。

前缀索引兼顾索引大小和查询速度,但是其缺点是不能用于ORDER BY和GROUP BY操作,也不能用于Covering index(即当索引本身包含查询所需全部数据时,不再访问数据文件本身)。‍

mysql多索引结构_MySQL-索引结构详解相关推荐

  1. 如何查看mysql备份的情况_MySQL数据库备份详解(示例代码)

    原文:MySQL数据库备份详解 对于任何数据库来说,备份都是非常重要的 数据库复制不能取代备份的作用 比如我们由于误操作,在主数据库上删除了一些数据,由于主从复制的时间很短,在发现时,从数据库上的数据 ...

  2. mysql 用户管理表_Mysql—用户表详解(mysql.user)

    MySQL 数据库 Mysql-用户表详解(mysql.user) MySQL是一个多用户管理的数据库,可以为不同用户分配不同的权限,分为root用户和普通用户,root用户为超级管理员,拥有所有权限 ...

  3. mysql myisam表分区_MySQL 表分区详解MyiSam引擎和InnoDb 区别(实测)

    一.什么是表分区 通俗地讲表分区是将一大表,根据条件分割成若干个小表.mysql5.1开始支持数据表分区了. 如:某用户表的记录超过了1000万条,那么就可以根据入库日期将表分区,也可以根据所在地将表 ...

  4. mysql 长事务查询_MySQL长事务详解

    前言: 『入门MySQL』系列文章已经完结,今后我的文章还是会以MySQL为主,主要记录下近期工作及学习遇到的场景或者自己的感悟想法,可能后续的文章不是那么连贯,但还是希望大家多多支持.言归正传,本篇 ...

  5. mysql实现悲观锁_mysql 悲观锁详解

    悲观锁指的是对数据被外界(包括本系统当前的其他事务,以及来自外部系统的事务处理)修改持保守态度,因此,在整个数据处理过程中,将数据处于锁定状态.悲观锁的实现,往往依靠数据库提供的锁机制(也只有数据库层 ...

  6. mysql 主从同步权限_MYSQL 主从同步详解

    关于MYSQL主从同步 什么是MYSQL的主从复制 主从复制是指将一个服务器作为主服务器,所有的数据更新操作都在主服务器进行,并且将主服务器的数据同步到一个或多个从服务器,保证从服务器和主服务器的数据 ...

  7. mysql distinct效率优化_mysql distinct 用法详解及优化

    本事例实验用表task,结构如下 MySQL> desc task; +-------------+------------+------+-----+-------------------+- ...

  8. mysql as 后面字段_mysql 字段as详解及实例代码

    mysql 字段使用as 在mysql中,select查询可以使用AS关键字为查询的字段起一个别名,该别名用作表达式的列名,并且别名可以在GROUP BY,ORDER BY或HAVING等语句中使用. ...

  9. mysql binlog sql统计_mysql的binlog详解

    binlog是mysql记录操作的二进制日志文件,有三种格式可选,但是老旧的SBR已经不适合现在大多数业务需求,所以大多数都建议用MBR和RBR,即mixed或row,而解析他的原因,几乎都只有一个, ...

  10. mysql 分号子查询_MySQL子查询详解

    子查询指一个查询语句嵌套在另一个查询语句内部的查询,这个特性从 MySQL 4.1 开始引入,在 SELECT 子句中先计算子查询,子查询结果作为外层另一个查询的过滤条件,查询可以基于一个表或者多个表 ...

最新文章

  1. go 怎么等待所有的协程完成_Go语言入门必知教程-协程
  2. 深度隐式表达:为什么不用mesh,点云,体素等表示方法?
  3. UnicodeEncodeError: 'ascii' codec can't encode character....
  4. python挖长尾词 源码,如何用代码挖局长尾关键词
  5. VTK:多重渲染窗口用法实战
  6. find command基本使用
  7. 前端学习(2757):text基本使用
  8. C++ 以对象管理资源
  9. Android设备 D获取,如何获取Android设备名称(常用ADB命令介绍)
  10. python 调用js类_Python 调用 JS 常用的4种方式,带你学会如何解密
  11. AI加持,计算机要拥有嗅觉了;GPU终于可用于Google Compute Engine | AI开发者头条
  12. TCPIP详解卷一概述 学习记录 2020/4/13
  13. 【教学类-07-02】20220330 5以内加减法不重复题 及生成word打印docx纸(方法二)(Python VS)
  14. ClickHouse的表引擎
  15. maven 使用assembly 进行打包
  16. Linux开发板网络直连电脑的设置方法
  17. R语言中的ggmap包
  18. Ubuntu安装“启动引导器”的设备选哪一项,选默认还是选/boot分区?
  19. DWR中文文档v0.9 03
  20. layui选项卡切换及右键的动态操作(新增、切换、删除)

热门文章

  1. LR中Action,Transaction,Rendezvous,SubmitData的插入顺序请注意
  2. 中科同向 备份软件 引领科技 存储未来
  3. 在线公开课 | 前端工程师如何突破瓶颈更好地变现自己
  4. jave 逻辑运算 vs 位运算 + Python 逻辑运算 vs 位运算
  5. studio--常见设置
  6. jQuery 方法 十四. html()方法和text()方法
  7. git pull命令模式
  8. 会计基础第八章内容2
  9. linux线上CPU100%排查
  10. linux之systemctl命令