“告警了!告警了!”。
"什么告警了?"正在睡梦中迷糊的小王突然被运维同事的一个电话叫醒,顿时一脸惊愕。
“慢查询!客户报障了!赶紧起来处理啊!”
小王赶紧打开便携,远程连上环境查找问题所在,最终发现该慢查询是一条子查询。“不对啊,相同语句昨天还没报慢查询啊?”
不过小王很快得出了原因。这条慢查询的问题在于:子查询的内部查询本来可以将数据汇聚后再输出到外部查询,但由于没有做汇聚,因此当数据量大的时候,就会很慢!
找到症结所在,小王立马将优化后的sql语句通过运维同事转给客户,该告警终于得以解决。
“看来得好好整理下子查询了!”,趁着思路清晰,小王开始整理了起来…
01 什么是子查询?
子查询是嵌套在另一个查询中的查询,在InfluxQL语法中一般放在from语句中,以增强代码的灵活性。子查询主要有以下几大分类:
标量子查询(scalarsubquery):返回1行1列一个值
行子查询(rowsubquery):返回的结果集是 1 行 N 列
列子查询(columnsubquery):返回的结果集是 N 行 1列
表子查询(tablesubquery):返回的结果集是 N 行 N 列
例如在查询语句:
select first(sum_f1)/first(sum_f2) from (select sum(f1) as sum_f1 from mst), (select sum(f2) as sum_f2 from mst)
使用了两个子查询,分别是从表mst中求得f1和f2两列之和,并将结果sum_f1和sum_f2作为外部查询的源,供外层查询语句使用。
GaussDB(for Influx)子查询的一般语法为SELECT_clause FROM (SELECT_statement ) […]。在处理子查询时的逻辑如下图所示。
系统会首先处理子查询语句,子查询的结果被缓存起来,作为外查询的数据源,最终由外层查询处理完成后将结果返回给客户。
02 子查询的使用场景
子查询用在一次简单查询无法处理的情况下,或者是基于一个查询的数据做进一步的处理,比如想找出每个分组的最小值中最大的三个:
SELECT top (v,3)
FROM (
SELECT min (value) AS v
FROM mst
GROUP BY tag1
)
子查询为我们带来了很大的灵活性,但是原则上不推荐使用子查询。原因很简单,相比于普