小 T 導讀:作為一款專業的時序資料庫(Time Series Database,TSDB),為滿足使用者在不同場景下的查詢需求,TDengine 提供了豐富的查詢功能。除了一些主要的查詢外,還包括多表聚合查詢、降采樣查詢及連續查詢,本文将從實際操作層面對這三種特殊查詢進行解讀。
查詢資料
主要查詢功能
TDengine 采用 SQL 作為查詢語言,應用程式可以通過 REST API 或連接配接器發送 SQL 語句,使用者還可以通過 TDengine 指令行工具 taos 手動執行 SQL 即席查詢(Ad-Hoc Query)。TDengine 支援如下查詢功能:
單列、多列資料查詢
- 标簽和數值的多種過濾條件:>, <, =, <>, like 等
- 聚合結果的分組(Group by)、排序(Order by)、限制輸出(Limit/Offset)
- 數值列及聚合結果的四則運算
- 時間戳對齊的連接配接查詢(Join Query: 隐式連接配接)操作
- 多種聚合/計算函數: count, max, min, avg, sum, twa, stddev, leastsquares, top, bottom, first, last, percentile, apercentile, last_row, spread, diff 等
例如:在指令行工具 taos 中,我們需要從表 d1001 中查詢出 voltage > 215 的記錄,按時間降序排列,僅僅輸出如下 2 條結果。
taos> select * from d1001 where voltage > 215 order by ts desc limit 2;
ts | current | voltage | phase |
======================================================================================
2018-10-03 14:38:16.800 | 12.30000 | 221 | 0.31000 |
2018-10-03 14:38:15.000 | 12.60000 | 218 | 0.33000 |
Query OK, 2 row(s) in set (0.001100s)
為滿足物聯網場景的需求,TDengine 還支援幾個特殊的函數,比如 twa(時間權重平均)、spread (最大值與最小值的差)、last_row(最後一條記錄)等,未來還将有更多與物聯網場景相關的函數添加進來。
多表聚合查詢
在物聯網場景中,往往同一個類型的資料采集點有多個。TDengine 采用超級表(STable)的概念來描述某一個類型的資料采集點,一張普通的表來描述一個具體的資料采集點。同時 TDengine 使用标簽來描述資料采集點的靜态屬性,一個具體的資料采集點有具體的标簽值。
通過指定标簽的過濾條件,TDengine 實作了将超級表(某一類型的資料采集點)所屬的子表統一進行聚合查詢。值得一提的是,對普通表的聚合函數以及絕大部分操作都适用于超級表,文法完全一樣。
示例一
在 TAOS Shell 查找加利福尼亞州所有智能電表采集的電壓平均值,并按照 location 分組。代碼如下所示:
taos> SELECT AVG(voltage) FROM meters GROUP BY location;
avg(voltage) | location |
=============================================================
222.000000000 | California.LosAngeles |
219.200000000 | California.SanFrancisco |
Query OK, 2 row(s) in set (0.002136s)
示例二
在 TAOS shell 查找 groupId 為 2 的所有智能電表過去 24 小時的記錄條數,電流的最大值。代碼如下所示:
taos> SELECT count(*), max(current) FROM meters where groupId = 2 and ts > now - 24h;
cunt(*) | max(current) |
==================================
5 | 13.4 |
Query OK, 1 row(s) in set (0.002136s)
需要注意的是,TDengine 僅容許對同屬于一個超級表的表之間進行聚合查詢,不同超級表之間的聚合查詢并不支援。
降采樣查詢、插值
除了上述場景,在物聯網場景中,我們還經常需要通過降采樣(down sampling)将采集的資料按時間段進行聚合。TDengine 提供了一個簡便的關鍵詞——interval(等間隔視窗),讓按照時間視窗進行的查詢操作變得極為簡單。比如,對智能電表 d1001 采集的電流值按每 10 秒鐘求和:
taos> SELECT sum(current) FROM d1001 INTERVAL(10s);
ts | sum(current) |
======================================================
2018-10-03 14:38:00.000 | 10.300000191 |
2018-10-03 14:38:10.000 | 24.900000572 |
Query OK, 2 row(s) in set (0.000883s)
同樣,降采樣操作也适用于超級表,比如将加利福尼亞州所有智能電表采集的電流值按每秒鐘求和:
taos> SELECT SUM(current) FROM meters where location like "California%" INTERVAL(1s);
ts | sum(current) |
======================================================
2018-10-03 14:38:04.000 | 10.199999809 |
2018-10-03 14:38:05.000 | 32.900000572 |
2018-10-03 14:38:06.000 | 11.500000000 |
2018-10-03 14:38:15.000 | 12.600000381 |
2018-10-03 14:38:16.000 | 36.000000000 |
Query OK, 5 row(s) in set (0.001538s)
此外,降采樣操作也支援時間偏移,比如:将所有智能電表采集的電流值按每秒鐘求和,但要求每個時間視窗從 500 毫秒開始:
taos> SELECT SUM(current) FROM meters INTERVAL(1s, 500a);
ts | sum(current) |
======================================================
2018-10-03 14:38:04.500 | 11.189999809 |
2018-10-03 14:38:05.500 | 31.900000572 |
2018-10-03 14:38:06.500 | 11.600000000 |
2018-10-03 14:38:15.500 | 12.300000381 |
2018-10-03 14:38:16.500 | 35.000000000 |
Query OK, 5 row(s) in set (0.001521s)
衆所周知,在物聯網場景裡每個資料采集點采集資料的時間較難同步,但很多分析算法(比如 FFT)需要把采集的資料嚴格按照時間等間隔地對齊,在很多系統裡,這需要應用自己寫程式來處理,但使用 TDengine 的降采樣操作這個需求便能輕松解決了。
如果一個時間間隔裡沒有采集的資料,TDengine 還提供插值計算的功能。
寫在最後
時序資料的查詢場景多種多樣,從使用者需求出發,TDengine 進行了一系列查詢功能的設計和優化。本文詳細介紹了 TDengine 中的幾種複雜查詢功能,如果大家在實操中遇到問題,可以将本文當做執行手冊進行查閱,對于還無法解決的問題,還可以加小 T 微信,進入 TDengine 技術社群深入交流。
::: hljs-center