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 将条目插入全文索引。
排序索引构建和压缩表
对于压缩表,之前索引创建方法会将条目追加到压缩页和未压缩页。当修改日志(表示压缩页上的空闲空间)已满时,压缩页将被重新压缩。如果由于空间不足而导致压缩失败,则该页将被拆分。对于排序索引构建,条目仅追加到未压缩页。当未压缩页已满时,它会被压缩。使用自适应填充来确保在大多数情况下压缩成功,但如果压缩失败,则该页将被拆分并再次尝试压缩。此过程将持续进行,直到压缩成功。有关 B 树页压缩的更多信息,请参见第 17.9.1.5 节“InnoDB 表的压缩工作原理”。
排序索引构建和重做日志记录
在排序索引构建期间,重做日志记录 被禁用。相反,有一个检查点来确保索引构建能够承受意外退出或故障。检查点强制将所有脏页写入磁盘。在排序索引构建期间,页清理程序 线程会定期收到信号以刷新脏页,以确保检查点操作可以快速处理。通常,页清理程序线程在干净页的数量低于设定阈值时刷新脏页。对于排序索引构建,脏页会立即刷新以减少检查点开销并使 I/O 和 CPU 活动并行化。
排序索引构建和优化器统计信息
排序索引构建可能会导致优化器 统计信息与通过之前索引创建方法生成的统计信息不同。统计信息的差异(预计不会影响工作负载性能)是由于用于填充索引的不同算法造成的。