TL;DR InfluxDB技术技巧 - DISTINCT()与INTO子句的缺失数据,MAX()的意外时间戳等

导航至

当您将一个函数INTO 子句GROUP BY time() 子句结合使用时会发生什么?偶尔,会出现一些奇怪的结果。在这篇文章中,我们将描述在SELECT 语句中使用InfluxQL函数时的意外情况。

使用DISTINCT()和INTO子句时的缺失数据

问题:我正在尝试将DISTINCT() 函数的结果写入不同的测量。问题是——没有INTO 子句的查询结果和带有INTO 子句的查询结果不同。这是预期的行为吗?我觉得我遗漏了什么。

仅仅是DISTINCT()

> SELECT DISTINCT("personality_type") FROM "twins"

name: twins
time                  distinct
----                  --------
1970-01-01T00:00:00Z  a                 
1970-01-01T00:00:00Z  b                   <--- Three results!
1970-01-01T00:00:00Z  uncategorizable

DISTINCT() 与INTO

> SELECT DISTINCT("personality_type") INTO "twin_types" FROM "twins"

name: result
time written
---- -------
1970-01-01T00:00:00Z 3      <--- Three written points!

> SELECT * FROM "twin_types"

name: twin_types
time                  distinct
----                  --------
1970-01-01T00:00:00Z  uncategorizable  <--- Just one point!

A:您所观察到的行为是预期的行为;这取决于InfluxDB如何识别单个以及它如何处理重复的点。

请注意,没有INTO子句的DISTINCT()查询的每个结果都有相同的时间戳。InfluxDB假定相同的时间戳和系列中的点都是重复的点。

当您在查询中添加INTO子句时,InfluxDB会将三个重复的点写入twin_types测量。当系统遇到重复的点时,它只是用最新的点覆盖之前的点,因此您在目标测量中只会得到一个结果。这有点出乎意料,但这就是您所看到的现象的解释。

使用MAX()和GROUP BY time()子句的意外时间戳

问:我正在尝试找到特定时间间隔的最大鸡蛋数量。在max列中的结果很准确,但time列中的时间戳并不是我所期望的。下面是我数据的简化版本。为什么时间戳看起来不对?

原始数据

> SELECT * FROM "house"

name: house
time                  eggs
----                  ----
2017-04-12T20:00:00Z  1     <--- Max value in the first 20-minute interval
2017-04-12T20:10:00Z  0
2017-04-12T20:20:00Z  3
2017-04-12T20:30:00Z  5     <--- Max value in the second 20-minute interval

我的查询

> SELECT MAX("eggs") FROM "house" WHERE time >= '2017-04-12T20:00:00Z' AND time <= '2017-04-12T20:30:00Z' GROUP BY time(20m)

name: house
time                  max
----                  ---
2017-04-12T20:00:00Z  1
2017-04-12T20:20:00Z  5     <--- I'd expect this timestamp to be 2017-04-12T20:30:00Z

A:您所看到的时间戳是GROUP BY time()子句的结果。该子句自动用标记相关时间间隔开始的标签覆盖了MAX()的原始时间戳。

在您的案例中,结果中的第二个时间戳(2017-04-12T20:20:00Z)指的是从2017-04-12T20:20:00Z2017-04-12T20:30:00Z之前的间隔,而不是原始数据中最大值发生的时间。几乎所有使用带有GROUP BY time()子句的InfluxQL函数的查询都会以这种方式覆盖时间戳。

  • 唯一的例外是SAMPLE()函数。有关更多信息,请参阅SAMPLE()文档

使用ELAPSED()和GROUP BY time()子句的意外一致性

问:我正在使用ELAPSED()来计算数据中中值之间的时间间隔。我得到的结果(见下文)总是显示相同的时间间隔。我很难相信我的中值总是恰好间隔十分钟。我是不是正确使用了ELAPSED()函数?

> SELECT ELAPSED(MEDIAN("clicks"),1m) FROM "puppies" WHERE time >= '2017-04-12T18:30:00Z' AND time <= '2017-04-12T19:10:00Z' GROUP BY time(10m)

name: puppies
time                  elapsed
----                  -------
2017-04-12T18:40:00Z  10
2017-04-12T18:50:00Z  10
2017-04-12T19:00:00Z  10

A:从语法角度来看,您正确使用了ELAPSED()函数,但您的查询不会给出您想要的结果。当您在嵌套函数和GROUP BY time()子句中使用ELAPSED()时,InfluxDB总是返回等于GROUP BY time()间隔的经过时间。

当您运行查询时,InfluxDB首先在指定的GROUP BY time()间隔内计算嵌套函数(MEDIAN())的结果,然后应用ELAPSED()函数。在第一步中,GROUP BY time()子句自动用标记每个GROUP BY time()间隔开始的标签覆盖了MEDIAN()的原始时间戳。当系统将ELAPSED()函数应用于第一步的结果时,它会遇到总是间隔十分钟的标签,而不是原始的中值时间戳。

 

接下来是什么

  • 下载的TICK-stack在我们的“下载”页面上是活跃的。
  • 云上部署:开始使用InfluxDB Cloud的免费试用,其中包括完全托管的集群、Kapacitor和Grafana。
  • 在您的服务器上部署:想在自己的服务器上运行InfluxDB集群吗?尝试免费的14天试用版。InfluxDB企业版,拥有直观的用户界面,用于部署、监控和均衡集群,以及管理备份和恢复。
  • 分享您的故事:300多家公司分享了他们如何通过InfluxDB取得成功的经历。提交您的评价,并作为感谢获得限量版卫衣。