“InnoDB:InnoDB 磁盘结构:Indexes”的版本间差异

来自Wikioe
跳到导航 跳到搜索
第23行: 第23行:




InnoDB 在创建或重建 B 树索引时执行批量加载。这种索引创建方法称为排序索引构建。 “'''innodb_fill_factor'''”配置选项定义了在排序索引构建期间每个 B 树页面上已填充的空间百分比,剩余的空间保留用于将来的索引增长。
InnoDB 在创建或重建 B 树索引时执行'''批量加载'''。这种索引创建方法称为'''排序索引构建'''。 “'''innodb_fill_factor'''”配置选项定义了在排序索引构建期间每个 B 树页面上已填充的空间百分比,剩余的空间保留用于将来的索引增长。
* 空间索引不支持排序索引构建。  
* 空间索引不支持排序索引构建。  
* “innodb_fill_factor”设置为 100 会使 Cluster index 页面中的空间的 1/16 留给将来的索引增长。
* “innodb_fill_factor”设置为 100 会使 Cluster index 页面中的空间的 1/16 留给将来的索引增长。

2021年4月18日 (日) 12:52的版本


聚集索引和二级索引【!!!】

每个 InnoDB 表都有一个称为“clustered index”的特殊索引,其中存储了行数据。通常,聚集索引与 primary key 同义

  1. 在表上定义“PRIMARY KEY”时,InnoDB 会将其用作聚集索引。为您创建的每个表定义一个主键。如果没有逻辑唯一且非空的列或列集,请添加一个新的“auto-increment”列,其值将自动填写。
  2. 如果您没有为表定义“PRIMARY KEY”,则 MySQL 将找到第一个“UNIQUE”索引,其中所有键列均为“NOT NULL”,而 InnoDB 将其用作聚集索引。
  3. 如果表没有“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。一旦定义了实例的页面大小,就不能在不重新初始化实例的情况下对其进行更改。支持的大小为 64KB32KB16KB(默认),8KB4KB

  • MySQL 5.7 中增加了对 32KB 和 64KB 页面大小的支持。
  • 使用特定 InnoDB 页面大小的 MySQL 实例不能使用来自使用不同页面大小的实例的数据文件或日志文件。

排序索引构建【???】

InnoDB 执行大容量加载,而不是在创建或重建索引时一次插入一个索引记录。这种索引创建方法也称为排序索引构建。【空间索引不支持排序索引构建】


索引构建分为三个阶段:

  1. 第一阶段,扫描 clustered index,并生成索引条目并将其添加到排序缓冲区。当 sort buffer 变满时,将对条目进行排序并将其写到临时中间文件中。此过程也称为“运行”。
  2. 第二阶段,将一个或多个运行写入临时中间文件,对文件中的所有条目执行合并排序。
  3. 第三个也是最后一个阶段,将已排序的条目插入 B-tree。


非排序索引构建 和 排序索引构建:

  1. 在引入排序索引构建之前,索引项是使用插入 API 一次插入一条记录到B树中的。这个方法包括打开一个 B-tree 游标来找到插入位置,然后使用乐观插入将条目插入到 B-tree 页面中。如果由于页面已满而导致插入失败,则将执行悲观插入,这涉及打开一个 B-tree 游标,并根据需要拆分和合并B树节点,以找到条目的空间。
    • 这种“自顶向下”建立索引的方法的缺点是搜索插入位置的开销以及B树节点的不断拆分和合并。
  2. 排序索引的构建使用“自下而上”的方法来构建索引。通过这种方法,在 B 树的所有级别都保留了对最右边的叶子页的引用。在必要的 B 树深度处分配最右边的叶子页,并根据其排序 Sequences 插入条目。一旦叶子页已满,节点指针将附加到父页面,并且为下一个插入分配同级叶子页。此过程将一直持续到插入所有条目为止,这可能会导致插入到根级别。分配同级页面后,将释放对先前固定的叶子页面的引用,并且新分配的叶子页面将成为最右边的叶子页面和新的默认插入位置。【?】

保留 B 树页面空间以用于将来的索引增长

要为将来的索引增长留出空间,可以使用“innodb_fill_factor”配置选项来保留一定比例的 B 树页面空间。(例如,将“innodb_fill_factor”设置为 80 会在排序索引构建过程中保留 B 树页面中 20%的空间。)

  • 此设置适用于 B 树叶子页面和非叶子页面。它不适用于用于“TEXT”或“BLOB”条目的外部页面。
  • 保留的空间量可能与配置的不完全一样,因为“innodb_fill_factor”值被解释为提示而不是硬限制。

排序索引构建和全文索引支持

全文索引支持排序索引生成。以前,SQL用于将条目插入到全文索引中。

排序索引构建和压缩表

对于压缩表,以前的索引创建方法将条目附加到压缩和未压缩的页面上。当修改日志(表示压缩页面上的可用空间)已满时,将重新压缩压缩页面。如果由于空间不足而导致压缩失败,则页面将被拆分。使用排序的索引构建时,条目仅追加到未压缩的页面。当未压缩的页面已满时,它将被压缩。自适应填充用于确保大多数情况下压缩成功,但是,如果压缩失败,则将拆分页面并再次尝试压缩。该过程一直持续到压缩成功为止。

排序索引构建和重做日志记录

Redo logging 在排序索引构建期间被禁用。而是使用 checkpoint 来确保索引构建可以承受崩溃或失败。该检查点强制将所有脏页写入磁盘。在排序索引构建过程中,会定期向 page cleaner 线程发送 signal 以刷新 dirty pages,以确保可以快速处理检查点操作。通常,当清除页数低于设置的阈值时,页面清除程序线程将刷新脏页。对于排序的索引构建,脏页将立即刷新,以减少检查点开销并并行化 I/O 和 CPU 活动。

排序索引构建和优化器统计信息

排序的索引生成可能会导致优化器统计信息与以前的索引创建方法生成的统计信息不同。统计数据的差异预计不会影响工作负载性能,这是由于用于填充索引的算法不同造成的。

InnoDB FULLTEXT 索引