calcite 自定义代价计算的元数据

125 阅读1分钟

一、背景

calcite是处理sql一个标准框架,使用非常广泛;calcite在构建逻辑计划后,有两种优化RBO(规则优化,常量折叠、算子下推等)和CBO(代价优化);基于代价的优化更容易适配当今各类数据库的查询;那么calcite是如何进行代价评估呢? 本文目标是搞清楚calcite计算代价流程,如何自定义自己的元数据;

二、原理分析

2.1 相关类图

image.png

  • RelOptCluster:代表在VolcanoPlanner执行优化过程中的上下文;
  • RelMetaDataQueryFactory:创建RelMetaDataQuery;
  • RelMetaDataQuery:用于在RelNode树上查询元数据的请求;
  • RelMetaDataProvider:接口定义,提供关系表达式的元数据
  • ChainedRelMetaDataProvider:连接多个RelMetaDataProvider;
  • RelectiveRelMetadataProvider: 反射的RelMetaDataProvider

整个调用过程是:左边的Provider注册到内存中,右边的MetaQuery去调用Provider的代理,获取节点的元数据

2.2 使用步骤

  1. 定义MetaDataProvider并设置到RelOptCluster中
public static RelMetadataProvider getMetadataProvider() {
    return ChainedRelMetadataProvider.of(ImmutableList.of(
            MetricStoreMetaHandler.INSTANCE,
            DefaultRelMetadataProvider.INSTANCE));
}
  • DefaultRelMetadataProvider.INSTANCE 是默认的ChianedMetadataprovider
  • MetricStoreMetaHandler.INSTANCE 是自定义的 MetricStoreMetaHandler
public static final RelMetadataProvider INSTANCE =
        ReflectiveRelMetadataProvider.reflectiveSource(
                Types.lookupMethod(
                        MetricStoreMetadata.MetricStoreMeta.class,
                        "getMetricStoreMetaInfo")
                , new MetricStoreMetaHandler());
  • 通过反射的方式获取 ReflectiveRelMetadataProvider 如类图中所见 ReflectiveRelMetadataProvider 包含有方法

待完成...