7.9. 查询规划

查询规划是转换GeoTools的过程 Query 用于特定后端的扫描和过滤器。GeoMesa中的查询规划包括以下几个步骤:

  1. 重写和优化CQL过滤器(如果有)以实现快速评估

  2. 基于可用的索引,CQL过滤器被拆分

  3. 选择其中一个可用索引来执行查询

  4. 逻辑查询计划由核心GeoMesa索引代码创建

  5. 为特定后端数据库创建物理查询计划

7.9.1. 滤光片分解

GeoMesa中的逻辑查询计划通常由用于确定扫描范围的“主”CQL过滤器和应用于匹配行的“次”CQL过滤器组成。例如,Z2索引将把任何空间谓词作为扫描范围处理,之后将应用任何额外的过滤器。

在查询规划的第二步中,对完整的过滤器进行分解并着眼于可用索引进行检查。对于每个索引,将确定一个主过滤器和一个辅助过滤器(如果有的话)。

例如,考虑筛选器::

BBOX(geom,0,0,10,10) AND
  dtg DURING 2017-01-01T00:00:00.000Z/2017-01-02T00:00:00.000Z
  AND name = 'alice'

该过滤器可以通过几种方式分解--对于Z2空间索引,主要过滤器是 BBOX ,对于Z3时空索引,主要过滤器是 BBOX 再加上 DURING ,而对于属性索引(假设‘name’已被索引),主过滤器是 name = 'alice'

7.9.2. 指标选择

由于完全跳过行比读取和筛选行要快得多,因此最好的查询计划通常是扫描最少行的计划。换句话说,最好的方案是具有最具选择性的主过滤器的方案。GeoMesa有两种确定最佳索引的方法--基于成本的或基于启发式的。使用的方法可以针对每个查询进行配置;请参见 查询索引查询规划类型 以获取更多信息。

7.9.2.1. 基于成本的战略

备注

缓存的统计数据以及基于成本的查询规划目前仅适用于Acumulo和Redis数据存储

GeoMesa将在摄取过程中收集统计数据,并存储它们以供查询规划使用。收集的统计数据包括:

  • 总计数

  • 默认几何、默认日期和任何索引属性的最小/最大(界限)

  • 默认几何、默认日期和任何索引属性的直方图

  • 任何索引属性的频率,按周划分

  • 任何索引属性的Top-k

  • 基于默认几何图形和默认日期的Z3直方图(如果两者都存在)

这些统计数据用于估计与给定主过滤器匹配的特征数量。将选择与最少要素匹配的主过滤器。

7.9.2.2. 启发式策略

启发式算法可用于仅基于查询过滤器的查询规划。优先考虑的事项包括:

  1. 使用ID索引的要素ID谓词

  2. 使用属性索引的高基数属性谓词

  3. 使用属性索引的属性相等谓词

  4. 使用Z3/XZ3索引的时空谓词

  5. 使用属性索引的属性范围谓词

  6. 使用Z2/XZ2索引的空间谓词

  7. 使用Z3/XZ3索引的时态谓词

  8. 使用属性索引的低基数属性谓词

此外,使用‘Join’属性索引的Acumulo数据存储将根据查询属性/转换来取消任何需要连接的谓词的优先级。

如果多个属性谓词同时具有最高优先级,则无法保证从该组中选择哪个属性谓词。

7.9.2.3. 自定义策略

通过使用系统属性指定类名,可以使用自定义策略实现 geomesa.strategy.decider 。类必须实现 org.locationtech.geomesa.index.planning.StrategyDecider

7.9.2.4. 基数暗示

已知具有许多不同值的属性,即高基数,可能会通过索引结构过滤掉许多误报,因此对属性索引的查询将触及相对较少的记录。相反,在最坏的情况下,只有两个不同值的布尔属性(例如)可能需要扫描整个数据集的一半。

当考虑属性索引时,基数提示可用于影响查询规划器。如果属性被标记为具有高基数,则该属性索引将被优先排序。相反,如果属性被标记为低基数,则属性索引将被取消优先级。有关设置基数的详细信息,请参见 配置属性基数

7.10. 说明查询计划

GeoMesa将在查询执行期间自动记录解释计划。这在调试查询问题时很有用,并且可以为加快执行时间的决策提供信息,例如何时添加附加索引或何时查询提示可能有用。

为了显示解释日志,请将您的日志系统配置为 org.locationtech.geomesa.index.utils.Explainertrace 水平。例如,在 reload4j 使用:

log4j.category.org.locationtech.geomesa.index.utils.Explainer=TRACE

您还可以在不执行查询的情况下生成解释日志,而不是被动地记录日志。在给定GeoMesa数据存储和查询的情况下,使用以下方法:

import org.locationtech.geomesa.index.utils.ExplainString

dataStore.getQueryPlan(query, explainer = new ExplainPrintln)

ExplainPrintln 将写信给 System.out 。或者,您可以使用 ExplainStringExplainLogging 将产出重新定向到其他地方。

使用二进制分发,您可以使用 explain 指挥部。看见 explain 了解更多详细信息。

如果使用查询拦截器,请参见 查询拦截器和守卫 启用有关拦截器更改的详细记录。

7.10.1. GeoServer

有关在Geoserver中启用解释记录的信息,请参阅 日志记录解释查询规划