本文介紹了時序表的索引機制,以及查詢時序表的最佳實踐。
背景信息
時序數據的模型請參見如何設計時序數據表,數據是按照時間序列來進行組織的。所以在時序數據表中,所有標記TAG的列(標簽列)會被建立為索引列,來表示每一條數據具體所屬于哪個時間序列,從而顯示數據的來源。
以時序數據表為例,具體請參見如何設計時序數據表,這些數據都屬于同一個時間序列,如下圖所示。
如果標簽列的值發生變化,則數據將屬于不同的時間序列。通常情況下,一個時間序列可以標記一個產生時序數據的數據源。
時序引擎會根據每個標簽列建立索引,其索引形態是倒排索引,以標簽列的列名和值作為索引鍵來索引所有擁有該鍵值對的時間序列,用于從時間序列維度快速定位某個標簽對應的數據范圍。隨著數據的不斷寫入,時序數據表的倒排索引將會呈現以下形態。
對于時間戳列,時序引擎會默認建立數據塊范圍索引,確保在海量時序數據中快速定位到需要查詢的數據范圍。但對于普通的Field列,時序引擎不會對數據建立索引。
使用建議
結合時序引擎的內部索引機制,對Lindorm時序引擎的時序表進行查詢時需要考慮以下幾點:
建議在查詢的條件語句中增加標簽列的等值過濾條件語句和時間戳列的過濾條件語句,避免條件語句中只有Field列過濾語句。
查詢的條件語句中如果包含多個標簽列過濾條件,且這幾個標簽列映射的時間線范圍存在包含關系,建議只需要保留選擇區分度最高的標簽列的過濾條件(例如上圖中的id列相對city列選擇區分度更高)。
查詢條件覆蓋的時間范圍過大可能會導致掃描過多的數據,進而導致查詢速度過慢,在這種情況下建議您可以縮小時間戳列的過濾范圍來提高查詢性能。
常見的時序查詢場景和查詢操作
如果需要復現以下查詢場景的結果,請下載相應的SQL腳本語句填寫樣例數據。
查詢時間范圍內的原始點
使用以下語句查詢余杭區內設備從2019-04-18 10:00:00至2019-04-18 10:30:00上報的全部SO2監控指標。
SELECT id, so2 FROM aqm WHERE district='yuhang' AND time >= '2019-04-18 10:00:00' AND time < '2019-04-18 10:30:00';
查詢結果如下。
查詢時序數據表中特定標簽列的所有標簽值
當將許多同類設備上報的數據接入到一張時序數據表中之后,有時會需要查詢接入設備的某個標簽的標簽值。例如下述SQL就可以查詢時序數據表 aqm
中接入的所有空氣質量監控設備的設備id
:
SELECT DISTINCT(id) FROM aqm;
查詢結果如下。
對于標簽列的查詢在存儲引擎層面默認會基于標簽索引進行查詢,因此無需擔心這樣的查詢會走全表掃描而產生性能問題。但若已接入的設備量非常多時,即使是走標簽索引其查詢耗時也可能會較長。
查詢時間精度的降采樣
查詢余杭區內設備從2019-04-18 10:00:00至2019-04-18 10:30:00上報的PM2.5和SO2監控指標,按5分鐘為粒度求平均值。
SELECT id, time, avg(pm2_5) AS avg_pm2_5, avg(so2) AS avg_so2 FROM aqm WHERE district='yuhang' AND time >= '2019-04-18 10:00:00' AND time < '2019-04-18 10:30:00' SAMPLE BY 5m;
查詢結果如下。
降采樣的實質是以時間序列為單位在時間維度的聚合。關于降采樣查詢的詳細說明請參見 降采樣。
查詢跨設備的聚合數據
查詢余杭區內設備從2019-04-18 10:00:00至2019-04-18 10:30:00上報的PM2.5和SO2監控指標,查詢按照5分鐘粒度的最大平均值。
SELECT max(avg_pm2_5) AS max_avg_pm25, max(avg_so2) AS max_avg_so2 FROM (SELECT district, id, time, avg(pm2_5) AS avg_pm2_5, avg(so2) AS avg_so2 FROM aqm WHERE district='yuhang' AND time >= '2019-04-18 10:00:00' AND time < '2019-04-18 10:30:00' SAMPLE BY 5m) GROUP BY district;
查詢結果如下。