一、背景
calcite是处理sql一个标准框架,使用非常广泛;calcite在构建逻辑计划后,有两种优化RBO(规则优化,常量折叠、算子下推等)和CBO(代价优化);基于代价的优化更容易适配当今各类数据库的查询;那么calcite是如何进行代价评估呢? 本文目标是搞清楚calcite计算代价流程,如何自定义自己的元数据;
二、原理分析
2.1 相关类图
- RelOptCluster:代表在VolcanoPlanner执行优化过程中的上下文;
- RelMetaDataQueryFactory:创建RelMetaDataQuery;
- RelMetaDataQuery:用于在RelNode树上查询元数据的请求;
- RelMetaDataProvider:接口定义,提供关系表达式的元数据
- ChainedRelMetaDataProvider:连接多个RelMetaDataProvider;
- RelectiveRelMetadataProvider: 反射的RelMetaDataProvider
整个调用过程是:左边的Provider注册到内存中,右边的MetaQuery去调用Provider的代理,获取节点的元数据
2.2 使用步骤
- 定义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 包含有方法
待完成...