InnoDB索引【Mysql InnoDB系列】

聚集索引和二级索引


每个InnoDB表都有一个特殊的索引叫做聚集索引(clustered index),这个索引上存放了所有表中的行。通常,聚集索引是主键的同义词。

  • 若在表上定义了主键,那么就会把这个主键作为聚集索引。最好给每张表都定义一个主键。如果没有逻辑上唯一非空的一列或多列,就给表加一个自增的列作为主键。
  • 若没有定义主键,mysql会使用第一个没有Null值的唯一索引作为聚集索引
  • 若没有主键或合适的唯一索引,InnoDB会内部生成一个叫做gen_clust_index的隐藏聚集索引,这个索引包含所有列和一个行ID。行是按照行ID的顺序排列的。行ID是一个6字节的区域,新行写入是单调递增。因此,行的排列顺序是按照物理写入的顺序。

聚集索引如何加速查询


通过聚集索引访问一行是很快的,因为扫描索引可以直接定位一整行的数据。如果表很大,相较于那种将行数据分散在不同索引记录页的存储结构,聚集索引的这种结构更加节约磁盘IO操作。

二级索引和聚集索引之间的关系


所有非聚集索引都是二级索引。在InnoDB中,每个二级索引中的记录都含有对应的主键列值,也就是这个二级索引中的唯一标志。InnoDB就是通过主键列值来搜索聚集索引中的行。

如果主键很长,那二级索引自然就会占用更多的空间,所以最好使用较短的主键。

索引的物理结构


除了空间索引之外,InnoDB索引都使用B-tree数据结构。空间索引使用R-trees,这是一种专门用于多维数据的特殊的索引结构。索引记录存放在B-tree或R-tree结构的叶子页上。索引页的默认大小为16k。

当新纪录写入聚集索引时,每个页会预留1/16的空间来用于将来可能出现的insert或update。如果索引记录是顺序写入(升序或降序),索引页可以被填充至大约15/16。若记录是以随机的顺序写入,索引页的饱满程度约为1/2至15/16区间。

当创建或重建B-tree索引时,InnoDB使用的是批量加载的方式。这种索引创建方式叫做排序索引创建(sorted index build)。InnoDB_fill_factor变量规定了每个B-tree索引页在被批量加载时填充的饱满程度百分比(在15/16的基础上)。innodb_fill_factor默认值为100,表示预留1/16用于索引页后续增长。另外,R-tree空间索引不支持排序索引创建。

排序序索引创建

创建索引分三个阶段,第一阶段会扫描聚集索引,然后生成索引条目并加入排序缓存。当排序缓存占满时,会使用外部临时文件。第二阶段将第一阶段生成的多个排序结果进行合并排序。第三阶段将最终排序结果写入B-tree。

如果一个InnoDB索引页的填充比降低至低于MERGE_THRESHOLD(默认为最大值50,最小为1),InnoDB会尝试将索引页(相邻的)合并以释放空间。

也可以设定表级别MERGE_THRESHOLD(对该表上所有索引生效):

ALTER TABLE t1 COMMENT='MERGE_THRESHOLD=40';

甚至是索引级别MERGE_THRESHOLD:

ALTER TABLE t1 ADD KEY id_index (id) COMMENT 'MERGE_THRESHOLD=40';

但对于自动生成的聚集索引GEN_CLUST_INDEX,只能使用表级别的或实例级别的MERGE_THRESHOLD

innodb_page_size配置选项用于为Mysql实例中的所有InnoDB表空间定义页面大小(page size)。这个选项只能在初始化实例时配置。页面大小支持64KB,32KB,16KB,8KB和4KB,其中32KB和64KB是5.7中新加入的支持,16KB为默认大小。

你可能感兴趣的:(InnoDB索引【Mysql InnoDB系列】)