InnoDB:InnoDB 磁盘结构:Indexes
聚集索引和二级索引【!!!】
每个 InnoDB 表都有一个称为“clustered index”的特殊索引,其中存储了行数据。通常,聚集索引与 primary key 同义。
- 在表上定义“PRIMARY KEY”时,InnoDB 会将其用作聚集索引。为您创建的每个表定义一个主键。如果没有逻辑唯一且非空的列或列集,请添加一个新的“auto-increment”列,其值将自动填写。
- 如果您没有为表定义“PRIMARY KEY”,则 MySQL 将找到第一个“UNIQUE”索引,其中所有键列均为“NOT NULL”,而 InnoDB 将其用作聚集索引。
- 如果表没有“PRIMARY KEY”或合适的“UNIQUE”索引,则 InnoDB 在包含行 ID 值的合成列上内部生成名为“GEN_CLUST_INDEX”的隐藏聚集索引。这些行由 InnoDB 分配给该表中的行的 ID 排序。行 ID 是一个 6 字节的字段,随着插入新行而单调增加。因此,按行 ID 排序的行实际上在插入 Sequences 上。
聚集索引如何加快查询速度
通过聚集索引访问行是快速的,因为索引搜索直接导致包含所有行数据的页面。如果表很大,则与使用不同于索引记录的页面存储行数据的存储组织相比,聚集索引体系结构通常可以节省磁盘 I/O 操作。
二级索引如何与聚集索引相关
除聚集索引以外的所有索引都称为“secondary indexes”(二级索引、第二索引、辅助索引)。在 InnoDB 中,辅助索引中的每个记录都包含该行的主键列以及为该辅助索引指定的列。 InnoDB 使用此主键值在聚集索引中搜索行。
- 如果主键较长,则辅助索引将使用更多空间,因此具有较短的主键是有利的。
InnoDB 索引的物理结构
除空间索引外,InnoDB 索引是B-tree数据结构。空间索引使用R-trees,这是用于索引多维数据的专用数据结构。索引记录存储在其 B 树或 R 树数据结构的叶页中。索引页的默认大小为 16KB。
当将新记录插入 InnoDB clustered index 时,InnoDB 会尝试使页面的 1/16 空闲,以供将来插入和更新索引记录。如果按 Sequences 插入索引记录(升序或降序),则所得到的索引页约为 15/16 装满。
- 如果以随机 Sequences 插入记录,则页面的容量为 1/2 到 15/16。【???】
InnoDB 在创建或重建 B 树索引时执行批量加载。这种索引创建方法称为排序索引构建。 “innodb_fill_factor”配置选项定义了在排序索引构建期间每个 B 树页面上已填充的空间百分比,剩余的空间保留用于将来的索引增长。
- 空间索引不支持排序索引构建。
- “innodb_fill_factor”设置为 100 会使 Cluster index 页面中的空间的 1/16 留给将来的索引增长。
如果 InnoDB 索引页的填充因子下降到“MERGE_THRESHOLD”以下(如果未指定,默认值为 50%),则 InnoDB 尝试收缩索引树以释放页面。
- “MERGE_THRESHOLD”设置适用于 B 树和 R 树索引。
您可以通过在初始化 MySQL 实例之前设置“innodb_page_size”配置选项来为 MySQL 实例中的所有 InnoDB 表空间定义 page size。一旦定义了实例的页面大小,就不能在不重新初始化实例的情况下对其进行更改。支持的大小为 64KB,32KB,16KB(默认),8KB 和 4KB。
- MySQL 5.7 中增加了对 32KB 和 64KB 页面大小的支持。
- 使用特定 InnoDB 页面大小的 MySQL 实例不能使用来自使用不同页面大小的实例的数据文件或日志文件。