Mysql的InnoDB引擎-5.索引(2)

B+树索引

B+树索引的本质就是B+树在数据库中的实现。但是B+树索引在数据库中有一个特点就是高扇出性,因此在数据库中,B+树的层高一般都在2~4层,意味着查询某一个键值的行记录最多需要2~4次IO。B+树索引分为聚集索引辅助索引

聚集索引

聚集索引就是根据数据表的主键构造一颗B+树,同时叶子节点中存放的即为整张表的行记录数据,也将聚集索引的叶子节点成为数据页。

聚集索引的存储并不是物理结构上连续的,而是逻辑上连续的。

  • 页是通过双向链表连接,页按照主键的顺序排序。
  • 每个页中的记录也是通过双向链表进行维护的,物理存储上可以同样不按照主键存储。

辅助索引

辅助索引也称为非聚集索引,叶子节点并不包含行记录的全部数据。叶子节点除了包含键值之外,每个叶子节点中的索引行中还包含了一个书签。

该书签是用来告诉InnoDB存储引擎哪里可以找到与索引相对应的行数据,存储的具体内容是聚集索引的键。

辅助索引的存在并不影响数据在聚集索引的组织,所以每个表可以创建多个辅助索引,当通过辅助索引查询数据的时候,InnoBD先通过辅助索引查询到主键索引的主键,然后再通过主键索引来找到一个完整的行记录。

索引管理

通过Alter table或者create/drop index 创建或者删除索引。查看某个表的索引可以通过 show index from table_name,结果如下图:

  • Table:索引所在的表名
  • Non_unique:非唯一索引,primary_key为0,如果是非唯一索引值为1
  • Key_name:索引的名字
  • Seq_in_index:索引中该列的位置
  • Column_name:索引列的名字
  • Collation:列以什么方式存放在索引中,可以是A或者NULL。B+树索引是A,即排序的。NULL表示非排序的(比如自适应Hash索引)
  • Cardinality:表示索引中谓一致的数据的预估值。Cardinality / 表行数尽可能接近1,如果非常小,这个索引的意义就很小。
  • Sub_part:是否是列的部分索引,如果不为NULL,表示对某一列的前N个字符进行索引。
  • Packed:关键字如何被压缩。如果没有压缩,NULL
  • NULL:是否索引列含有NULL值,如果是yes,表示可以允许NULL值
  • Index_type:索引类型,InnoDB只支持B+树索引
  • Comment:注释信息

Cardinality

Cardinality值表示索引中不重复记录数据的预估值。Cardinality/n rows in table应该尽可能的接近1。

统计Cardinality是通过采样的方法完成的。Cardinality统计信息的更新发生在Insert或者Update操作中,但是并不是每次都会更新。更新策略为:

  • 表中1/16的数据已经发生过变化。
  • stat_modified_counter>2000000000 (stat_modified_counter用来记录发生变化的次数)

Cardinality采样是根据索引的8个叶子节点进行采样,然后通过8个节点预估出所有叶子节点的总和,得到Cardinality值,所以每次得到的值都不是准确不变的。

计算公式 Cardinality = (P1+P2+....+P8)* A/8   P为采样的节点1~8,A为叶子节点数量。

注意:如果表足够小,那么表的索引叶子节点小于或者等于8,那么每次计算的值就会相同。

Index的其他内容

Fast Index Creation

5.5之前Mysql数据库对于索引的添加或者删除这类的DDL操作,过程为:

  • 首先创建一张临时表,表结构为通过alter table新定义的结构
  • 然后把原表数据导入到临时表
  • 接着删除原表
  • 最后把临时表命名为原来的表名

如果对一个很大的表进行这样的操作,非常损耗性能。所以出先了Fast Index Creation(FIC)的索引创建方式。

对于辅助索引的创建,在对应的表加上S锁。创建索引过程中不需要重建表,删除索引只要更新内部视图即可,并将辅助索引的空间标记为可用,同时删除Mysql数据库内内部视图上对该表的索引定义即可。

注意:临时表创建的目录是通过tmpdir参数设置,要保证有足够空间创建临时表。FIC操作的时候,加了S锁,所以这个时候只能对数据进行读操作。

Online Schema Change

在线架构改变(OSC)过程:

  • init:初始化阶段,验证工作,是有有主键外键触发器等验证
  • createCopyTable:创建一个和原表一样的新表
  • alterCopyTable:对创建新表进行alter操作,比如新增索引或者列等
  • createDeltasTable:创建deltas表,为了创建触发器使用,之后对原表的DML操作会被记录deltas中。
  • createTriggers:创建触发器。触发操作产生的记录被写入deltas表中。
  • startSnpshotXact:开始OSC操作的事务。
  • selectTableIntoOutFile:将原表数据写入新表(为了减少锁定原表的时间,通过分片将数据输出到多个外部文件,默认分片500000)
  • dropNCIndexs:导入新表前,删除新表中的所有辅助索引
  • loadCopyTable:将导出的分片数据导入新表。
  • replayChanges:将OSC过程中原表的DML操作的记录应用到新表中,这些记录被保存到deltas中。
  • recreateNCIndexs:重新创建辅助索引
  • replayChanges:再次进行DML日志的回放操作,这些日志是在上述创建辅助索引中过程中新产生的日志。
  • swapTables:将原表和新表交换名字。需要锁定两张表,不允许新数据产生。(因为改名是很快的操作,所以锁定时间很短)

Online DDL

5.6之后支持在线DDL,一下操作都可以通过在线DDL解决:

  • 辅助索引的创建和删除
  • 改变自增长值
  • 添加或删除外键约束
  • 列的重命名

具体语法内容相关,查看博客: https://www.cnblogs.com/cchust/p/4639397.html

猜你喜欢

转载自www.cnblogs.com/wangb0402/p/12745341.html