TL;DR InfluxDB技术技巧 - DISTINCT()与INTO子句的缺失数据,MAX()的意外时间戳等
作者:Regan Kuchan / 产品,开发者
2017年4月13日
导航至
当您将一个函数与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:00Z
到2017-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取得成功的经历。提交您的评价,并作为感谢获得限量版卫衣。