基于成本的优化器

当 Manticore 执行全扫描查询时,它可以使用普通扫描来检查每个文档是否符合过滤条件,或者采用额外的数据和/或算法来加速查询执行。Manticore 使用基于成本的优化器(CBO),也称为“查询优化器”,来决定采用哪种方法。

CBO 还可以提升全文查询的性能。详情见下文。

如果 CBO 认为替换一个或多个查询过滤器能提升性能,它可能会用以下实体之一替换:

  1. docid 索引 利用存储在 .spt 扩展名文件中的特殊仅包含 docid 的二级索引。除了提升文档 ID 上的过滤器性能外,docid 索引还用于加速文档 ID 到行 ID 的查找,以及加快守护进程启动时大规模 killlist 的应用。
  2. 列式扫描 依赖于列式存储,仅能用于列式属性。它扫描每个值并对其进行过滤测试,但经过高度优化,通常比默认方法更快。
  3. 二级索引 默认为所有属性(除 JSON 外)生成。它们使用 PGM 索引 以及 Manticore 内置的倒排索引来检索对应于某个值或值范围的行 ID 列表。二级索引存储在扩展名为 .spidx.spjidx 的文件中。 有关如何为 JSON 属性生成二级索引的信息,请参见 json_secondary_indexes

优化器使用各种属性统计信息来估算每条执行路径的成本,包括:

  1. 属性内数据分布信息(直方图,存储在 .sphi 文件中)。直方图在数据索引时自动生成,是 CBO 的主要信息来源。
  2. 来自 PGM(二级索引)的信息,有助于估算需要读取的文档列表数量。这有助于评估文档列表合并性能并选择合适的合并算法(优先队列合并或位图合并)。
  3. 列式编码统计,用于估算列式数据解压性能。
  4. 列式最小-最大树。虽然 CBO 使用直方图估算应用过滤器后剩余的文档数量,但它还需要确定过滤器处理了多少文档。对于列式属性,部分评估最小-最大树可实现此目的。
  5. 全文字典。CBO 利用词项统计信息来估算全文树的评估成本。

优化器计算查询中每个过滤器的执行成本。由于某些过滤器可以被多种不同实体替代(例如,对于文档 ID,Manticore 可以使用普通扫描、docid 索引查找、列式扫描(如果文档 ID 是列式的)和二级索引),优化器会评估所有可用组合。但组合数最大限制为 1024。

为了估算查询执行成本,优化器计算执行查询时最重要操作的估计成本。它使用预设常数来表示每个操作的成本。

优化器比较每条执行路径的成本,选择成本最低的路径来执行查询。

在处理带有属性过滤器的全文查询时,查询优化器在两种可能的执行路径之间做出决定。一种是执行全文查询,检索匹配项,然后使用过滤器。另一种是用上述一个或多个实体替换过滤器,从中获取行 ID 并注入全文匹配树。这样,全文搜索结果将与全扫描结果相交。查询优化器估算全文树评估的成本和计算过滤器结果的最佳路径。基于此信息,优化器选择执行路径。

另一个需要考虑的因素是多线程查询执行(当启用 pseudo_sharding 时)。CBO 知道某些查询可以多线程执行,并将此纳入考虑。CBO 优先考虑较短的查询执行时间(即延迟)而非吞吐量。例如,如果使用列式扫描的查询可以多线程执行(占用多个 CPU 核心),且比单线程使用二级索引执行的查询更快,则优先选择多线程执行。

使用二级索引和 docid 索引的查询始终在单线程中运行,因为基准测试表明使它们多线程几乎没有收益。

目前,优化器仅使用 CPU 成本,不考虑内存或磁盘使用。

Last modified: August 28, 2025