目的: 带大家了解查询条件过滤是如何实现及编写高效过滤条件
阅读对象: 开发人员、构架师、运维人员等
一、应用背景
大家知道,TDengine 的查询语句 where 条件中可以对普通列及标签列进行各种组合过滤查询,那这些过滤是如何高效实现的呢?今天带大家一起来了解一下。
二、整体流程图
我们先熟悉下查询过滤的整体流程,整体流程图对实现过程进行了概括及抽象,这样有助于大家能快速理解整个实现过程
小结:先对 TAG 过滤,过滤出查询需要在哪些子表中进行,再对每个子表中的数据进行过滤
三、查询过滤优化
上面把查询过滤的流程说了,接下来再说下过滤时的优化方法。
1、限定时间主列范围
时序数据数量庞大,不适合全范围查询,时间主列是主索引列,过滤非常快,已知时间范围的尽可能在过滤条件中增加间主列范围
2、TAG 列增加索引
TDengine 的第一列时间主列是默认有索引的,但其它 TAG 列默认没有索引,如果在过滤条件中频繁使用某些 TAG 列做过滤,最好为这些 TAG 列创建标签索引。TDengine 普通列上目前还不支持创建索引,主要原因是普通列数据过于庞大,创建索引过程慢及索引占据空间也会非常庞大等原因。
创建标签索引可参考 :标签索引
3、普通列展括号优化
举例:
对于 WHERE 中询过滤条件,主要由 AND 、 OR 、括号三个组合成的,优化依据以下公式:
假设 A B C D 分别为四个不同的过滤条件,c1 表示一个 int 类型普通列
举例 A :c1 > 10
B: c1 > 15
C: c1 < 20
D: c1 < 25
WHERE 语句 : (A and C ) and (B and D)
过滤一条记录 c1=18 , 需要计算四次才能得到结果 , 我们可以优先到两次计算出结果。
第一步 先把括号展开
(A and C ) and (B and D) -> A and C and B and D
因为都是 and 操作,所以可以直接去除括号
第二步 进行交换
A and C and B and D -> A and B and C and D
and 之间可以相互交换位置,不影响最后结果
第三步 合并
A and B and C and D -> B and C
A 和 B 相同操作符,都是大于操作,取最大者即可
C 和 D 相同操作符,都是小于操作,取最小者即可
小结:
展括号优化,可以对条件进行逻辑合并,减小计算次数
4、普通列平铺 OR 优化
如果我们的过滤条件中带有很多组合出来带括号的多层过滤条件,可以尝试把 OR 条件平铺,OR 条件平铺的好是从前向后只要有一个条件为 TRUE 了,就可以终止计算
where 条件为: A and ( B or ( C and D) )
= A and (BC or BD)
= ABC or ABD
(说明 : 如果 ABC 为 TRUE 后, ABD 不需要再计算)
同时可以把预测结果为 TRUE 概率高的表达式写到前面,概率低的写在后面