TL;DR InfluxDB 技术提示 - 使用 DISTINCT() 和 INTO 子句时数据丢失,使用 MAX() 时时间戳意外以及更多
作者:Regan Kuchan / 产品, 开发者
2017年4月13日
导航至
当您将函数与 INTO
子句 或 GROUP BY time()
子句结合使用时会发生什么? 有时会出现一些奇怪的结果。在这篇文章中,我们描述了在 SELECT
语句中使用 InfluxQL 函数时遇到的意外情况。
使用 DISTINCT() 和 INTO 子句时数据丢失
问: 我正在尝试将 DISTINCT()
函数的结果写入不同的 measurement。唯一的问题是 - 没有 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!
答: 您看到的行为是预期的行为;这归结于 InfluxDB 如何识别单个 point 以及如何处理重复的 point。
请注意,没有 INTO
子句的 DISTINCT()
查询的每个结果都具有相同的时间戳。InfluxDB 认为同一 series 中且具有相同时间戳的 point 是重复的 point。
当您将 INTO
子句添加到查询中时,InfluxDB 会将三个重复的 point 写入 twin_types
measurement。当系统遇到重复的 point 时,它只是用最新的 point 覆盖之前的 point,因此您最终在目标 measurement 中只有一个结果。这有点出乎意料,但这就是您所看到情况的解释。
使用 MAX() 和 GROUP BY time() 子句时时间戳意外
问: 我正在尝试查找特定时间间隔内的 maximum 鸡蛋数量。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
答: 您看到的时间戳是 GROUP BY time()
子句的结果。该子句会自动使用标记相关时间间隔开始的时间戳覆盖 MAX()
的原始时间戳。
在您的情况下,结果中的第二个时间戳 (2017-04-12T20:20:00Z
) 指的是 2017-04-12T20:20:00Z
和 2017-04-12T20:30:00Z
之前的时间间隔,而不是原始数据中 maximum 值发生的时间。几乎所有*使用 InfluxQL 函数和 GROUP BY time()
子句的查询都以这种方式覆盖时间戳。
- 唯一的例外是
SAMPLE()
函数。有关更多信息,请参阅SAMPLE()
文档。
使用 ELAPSED() 和 GROUP BY time() 子句时一致性意外
问: 我正在使用 ELAPSED()
来计算数据中 median 值之间的时间间隔。我得到的结果(见下文)始终显示相同的时间间隔。我很难相信 我的 median 值总是正好相隔十分钟。我是否正确使用了 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
答: 从语法角度来看,您正确使用了 ELAPSED()
函数,但您的查询不会给您带来您想要的结果。当您将 ELAPSED()
与嵌套函数和 GROUP BY time()
子句一起使用时,InfluxDB 始终返回等于 GROUP BY time()
间隔的 elapsed 值。
当您运行查询时,InfluxDB 首先在指定的 GROUP BY time()
间隔计算嵌套函数 (MEDIAN()
) 的结果,然后将 ELAPSED()
函数应用于这些结果。在第一步中,GROUP BY time()
子句会自动使用标记每个 GROUP BY time()
间隔开始的时间戳覆盖 MEDIAN()
的原始时间戳。当系统将 ELAPSED()
函数应用于第一步的结果时,它会遇到始终相隔十分钟的时间戳,而不是 MEDIAN()
值的原始时间戳。
下一步
- 下载 TICK-stack 的下载已在我们的“下载”页面上线。
- 云端部署: 免费试用 InfluxDB Cloud ,体验完全托管的集群、Kapacitor 和 Grafana。
- 在您的服务器上部署: 想在您的服务器上运行 InfluxDB 集群?免费试用 14 天 InfluxDB Enterprise ,体验用于部署、监控和重新平衡集群的直观 UI,以及管理备份和恢复。
- 讲述您的故事: 超过 300 家公司 分享了 InfluxDB 如何帮助他们成功的案例。提交您的客户评价,即可获得限量版连帽衫,以表感谢。