Mysql 排序索引构建
在创建或重建索引时,InnoDB 执行批量加载,而不是一次插入一条索引记录。这种索引创建方法也称为排序索引构建。空间索引不支持排序索引构建。
索引构建有三个阶段。在第一阶段,扫描聚簇索引,并生成索引条目并将其添加到排序缓冲区。当排序缓冲区已满时,对条目进行排序并将其写入临时中间文件。这个过程也称为“一轮”。在第二阶段,将一轮或多轮写入临时中间文件后,对文件中的所有条目执行归并排序。在第三阶段也是最后阶段,将已排序的条目插入到 B 树中;此最后阶段是多线程的。
在引入排序索引构建之前,使用插入 API 一次将索引条目插入到 B 树中一条记录。此方法涉及打开 B 树游标以查找插入位置,然后使用乐观插入将条目插入到 B 树页面中。如果由于页面已满而插入失败,则会执行悲观插入,这涉及打开 B 树游标,并根据需要拆分和合并 B 树节点以找到条目空间。这种“自上而下”的索引构建方法的缺点是搜索插入位置的成本以及 B 树节点的不断拆分和合并。
排序索引构建使用“自下而上”的方法来构建索引。通过这种方法,在 B 树的所有级别都保留对最右侧叶页面的引用。在必要的 B 树深度分配最右侧的叶页面,并根据其排序顺序插入条目。一旦叶页面已满,将节点指针附加到父页面,并为下一次插入分配兄弟叶页面。这个过程一直持续到插入所有条目,这可能导致插入到根级别。当分配兄弟页面时,释放先前固定的叶页面的引用,新分配的叶页面成为最右侧的叶页面和新的默认插入位置。
为未来的索引增长预留 B 树页面空间
要为未来的索引增长预留空间,可以使用 innodb_fill_factor 变量预留 B 树页面空间的百分比。例如,将 innodb_fill_factor 设置为 80 会在排序索引构建期间在 B 树页面中预留 20%的空间。此设置适用于 B 树的叶页面和非叶页面。它不适用于用于 TEXT 或 BLOB 条目的外部页面。预留的空间量可能不完全与配置相同,因为 innodb_fill_factor 值被解释为提示而不是硬限制。
排序索引构建和全文索引支持
全文索引支持排序索引构建。以前,使用 SQL 将条目插入到全文索引中。
排序索引构建和压缩表
对于压缩表,以前的索引创建方法将条目附加到压缩页面和未压缩页面。当修改日志(表示压缩页面上的可用空间)已满时,压缩页面将被重新压缩。如果由于空间不足导致压缩失败,则页面将被拆分。使用排序索引构建,条目仅附加到未压缩页面。当未压缩页面已满时,将其压缩。使用自适应填充以确保在大多数情况下压缩成功,但如果压缩失败,则拆分页面并再次尝试压缩。这个过程一直持续到压缩成功。
排序索引构建和重做日志记录
在排序索引构建期间禁用重做日志记录。相反,有一个检查点以确保索引构建能够承受意外退出或失败。检查点强制将所有脏页面写入磁盘。在排序索引构建期间,定期向页面清理线程发出信号以刷新脏页面,以确保检查点操作能够快速处理。通常,当干净页面的数量低于设定的阈值时,页面清理线程会刷新脏页面。对于排序索引构建,及时刷新脏页面以减少检查点开销并并行化 I/O 和 CPU 活动。
排序索引构建和优化器统计信息
排序索引构建可能导致优化器统计信息与以前的索引创建方法生成的统计信息不同。统计信息的差异预计不会影响工作负载性能,这是由于用于填充索引的算法不同。