当前位置: > > > InfluxDB时序数据库的安装使用教程5(连续查询CQ)

InfluxDB时序数据库的安装使用教程5(连续查询CQ)

五、连续查询

1,基本介绍

    连续查询 Continuous QueryCQ)是在数据库内部自动周期性跑着的一个 InfluxQL 的查询,InfluxDB 会将查询结果放在指定的数据表中。CQs 需要在 SELECT 语句中使用一个函数,并且一定包括一个 GROUP BY time() 语句。
(1)CQ 的目的:
  • 使用连续查询是最优的降低采样率的方式,连续查询和存储策略搭配使用将会大大降低 InfluxDB 的系统占用量。而且使用连续查询后,数据会存放到指定的数据表中,这样就为以后统计不同精度的数据提供了方便。
(2)CQ 的使用场景:
  • 采样和数据保留:使用 CQInfluxDB 的保留策略(RP)来减轻存储问题。结合 CQRP 自动将高精度数据降低到较低的精度,并从数据库中移除可分配的高精度数据。
  • 预先计算昂贵的查询:通过使用 CQ 预先计算昂贵的查询来缩短查询运行时间。使用 CQ 自动将普通查询的高精度数据下采样到较低的精度。较低精度数据的查询需要更少的资源并且返回更快。
  • 替换 HAVING 子句InfluxQL 不支持 HAVING 子句。通过创建 CQ 来聚合数据并查询 CQ 结果以达到应用 HAVING 子句相同的功能。
  • 替换嵌套函数:一些 InfluxQL 函数支持嵌套其他函数,大多数是不行的。如果函数不支持嵌套,可以使用 CQ 获得相同的功能来计算最内部的函数。然后简单地查询 CQ 结果来计算最外层的函数。

2,创建 CQ(基本语法)

(1)我们执行如下命令创建一个 CQ
  • 我们创建了一个叫做 cq_30mCQ 作用于 mydb 数据库上
  • cq_30m 告诉 InfluxDB30 分钟计算一次 measurementtemperature 并使用默认 RP 的字段 internalexternal 的平均值,然后把结果写入到使用默认 RP,两个字段分别是 mean_internalmean_externalmeasurement 名为 average_temperature 的数据中。
  • InfluxDB 会每隔 30 分钟对之前 30 分钟的数据跑一次这个查询。
注意:在 WHERE 子句中,cq_query 不需要时间范围。 InfluxDB 在执行 CQ 时自动生成 cq_query 的时间范围。cq_queryWHERE 子句中的任何用户指定的时间范围将被系统忽略。
CREATE CONTINUOUS QUERY "cq_30m" ON "mydb" 
BEGIN
  SELECT mean("internal") AS "mean_internal",mean("external") AS "mean_external"
  INTO "average_temperature"
  FROM "temperature"
  GROUP BY time(30m)
END

(2)下面是其他一些样例:
// 自动采样数据到另一个保留策略里
CREATE CONTINUOUS QUERY "cq_basic_rp" ON "mydb"
BEGIN
  SELECT mean("external") INTO "mydb2"."three_weeks"."average_external" FROM "temperature" GROUP BY time(1h)
END

// 使用逆向引用自动采样数据
CREATE CONTINUOUS QUERY "cq_basic_br" ON "mydb"
BEGIN
  SELECT mean(*) INTO "mydb2"."autogen".:MEASUREMENT FROM /.*/ GROUP BY time(30m),*
END

// 自动采样数据并配置CQ的时间边界
CREATE CONTINUOUS QUERY "cq_basic_offset" ON "mydb"
BEGIN
  SELECT mean("external") INTO "average_external" FROM "temperature" GROUP BY time(1h,15m)
END

3,创建 CQ(高级语法)

(1)InfluxDB 连续查询的高级语法如下,与基本语法不同的是,多了 RESAMPLE 关键字。高级语法里 CQ 的执行时间和查询时间范围则与 RESAMPLE 里面的两个 interval 有关系。
CREATE CONTINUOUS QUERY <cq_name> ON <database_name>
RESAMPLE EVERY <interval> FOR <interval>
BEGIN
  <cq_query>
END

(2)假设我们 bus_data 表中的数据如下:

(3)当我们使用高级语法创建 CQ 只配置执行时间间隔(RESAMPLE EVERY)时:
  • 这里配置了 30 分钟执行一次 CQ,没有指定 FOR interval,于是查询的时间范围还是 GROUP BY time(1h) 指定的一个小时。 
CREATE CONTINUOUS QUERY "cq_advanced_every" ON "transportation"
RESAMPLE EVERY 30m
BEGIN
  SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(1h)
END
  • 执行流程如下,可以看到这里的 8 点到 9 点这个区间执行了两次,第一次执行时间是 8:30,平均值是 (8+15+15)/ 3 = 12.6667,而第二次执行时间是 9:00,平均值是 (8+15+15+17) / 4=13.75,而且最后第二个结果覆盖了第一个结果。
  • 最终的结果如下:

(4)当我们使用高级语法创建 CQ 只配置查询时间范围(RESAMPLE FOR)时:
CREATE CONTINUOUS QUERY "cq_advanced_for" ON "transportation"
RESAMPLE FOR 1h
BEGIN
  SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(30m)
END
  • 因为只配置了时间范围,而没有配置 EVERY interval。这样,执行的时间间隔与 GROUP BY time(30m) 一样为 30 分钟,而查询的时间范围为 1 小时,由于是按 30 分钟分组,所以每次会写入两条记录。
  • 需要注意的是,cq_advanced_for 每次写入了两条记录,重复的记录会被覆盖。最终结果如下:

(5)当然我们也可以同时配置执行时间间隔和查询时间范围:
CREATE CONTINUOUS QUERY "cq_advanced_every_for" ON "transportation"
RESAMPLE EVERY 1h FOR 90m
BEGIN
  SELECT mean("passengers") INTO "average_passengers" FROM "bus_data" GROUP BY time(30m)
END
  • 这里配置了执行间隔为 1 小时,而查询范围 90 分钟,最后分组是 30 分钟,每次插入了三条记录。执行流程如下:
  • 同样重复的记录会被覆盖,最终结果如下:

4,显示所有已存在的 CQ

执行如下命令可以显示所有已存在的连续查询(会按照 database 作分组)
SHOW CONTINUOUS QUERIES

5,删除 CQ

执行如下命令删除指定的 CQ
注意CQ 一旦创建就不能修改了,我们必须 DROPCREATE 才行。
DROP CONTINUOUS QUERY "cq_30m" ON "mydb"
评论0