influxdb查询语句_InfluxDB 源码学习:查询优化

670731b1f6b7187204b693a492d1fb92.png

InfluxDB 2.0 使用 Flux 作为它的查询语言,分析一下下面这个查询语句(简称 Query A)是如何被执行的:

(bucket:

InfluxDB 作为数据库同样设计了逻辑查询计划和物理查询计划的创建和优化环节,整体流程:

  1. 解析查询语句,生成 flux.Spec 对象
  2. 将 Spec 对象转化成逻辑查询计划并优化
  3. 将逻辑查询计划转换成物理查询计划并优化

代码如下:

func 

flux.Spec 对象

flux.Spec 定义如下:

// Spec specifies a query.

flux.Spec 对象表示的是一个有向无环图(DAG),Query A 的结构大致如下:

from -> range -> filter -> window -> quantile

其中 Operations 表示查询语句当中的算子,Edges 则表示它们之间的关联,sorted 表示节点拓扑排序的顺序,用于后面创建查询计划。

逻辑查询优化

InfluxDB 的逻辑查询优化算法(准确的说是 flux 的)比较简单,深度遍历算子,如果遍历到的算子有配置优化规则,就执行优化规则,将节点转换成新节点,使用新的节点更换旧的节点。然后继续遍历。代码如下:

func 

第 5 ~ 14 行,创建遍历是要用到的 stack
第 17 ~ 43 行,深度遍历节点,其中:

  1. 第 24 行 matchRules 方法尝试对节点进行优化,并使用新的节点替换掉原来的节点,如果没有优化,返回的 newNode 和 node 是同一个对象
  2. 第 28 行,如果节点被优化了,使用 anyChanged 标记查询计划发生变化,完成此次遍历之后会重新遍历一遍,直到不再有节点被优化

目前 InfluxDB 还没有添加什么实际的逻辑查询优化规则,所以返回的逻辑查询计划其实没有发生变化。唯一不同的是逻辑查询阶段,会为 Query A 增加一个 yield 算子,感觉这个算子和关系型数据库的 projection 算子有些类似, 最终 yield 算子负责将数据推送给应用层。

最终得到的逻辑查询计划:

from -> range -> filter -> window -> quantile -> yield

物理查询优化

物理查询计划的创建过程很简单,而且和优化流程混合在了一起:

func 

第 2 行,调用和逻辑查询计划一样的查询优化器,只不过针对物理查询计划的优化规则比较多,将逻辑算子转换成对应类型的物理算子也充当了一种查询优化规则... 以此来完成逻辑查询计划到物理查询计划的转换。

InfluxDB 配置的物理查询计划优化策略如下:

// query/stdlib/influxdata/influxdb/rules.go

从代码上来看主要是一些算子下推的优化策略,应该不是很复杂。完成物理查询优化之后得到的最终查询计划:

ReadRange -> window -> quantile -> yield

逻辑查询优化中的 Range 和 Filter 算子都和 From 合并到一起了。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值