您可以使用以下方式,提高日誌查詢分析的速度。
增加Shard數量或開啟SQL獨享版
增加Shard可以提升讀寫能力,但只對新寫入的資料生效。Shard表示計算資源,Shard越多,計算越快,您需要保證平均每個Shard掃描的資料不多於5000萬條。您可以通過分裂Shard,增加Shard數量。具體操作,請參見分裂Shard。Shard的計費資訊,請參見活躍Shard租用費用。
SQL獨享版支援更多的分析操作並發數、更多的掃描資料量。
縮減查詢的時間範圍和資料量
時間範圍越大,查詢越慢。
適當縮短查詢的時間範圍可以更快地完成計算。
資料量越大,查詢越慢。
請盡量減少查詢的資料量。
多次重複查詢
當查詢不精確時,可以嘗試多次重複查詢。每次查詢時,底層加速機制會充分利用已有的結果進行分析,因此多次查詢可以使結果更加精確。
最佳化SQL分析語句
計算時間較長的查詢分析語句具備如下特點。
使用GROUP BY文法基於字串列進行分組統計。
使用GROUP BY文法基於多列(大於5列)進行分組統計。
在SQL分析語句中有產生字串的操作。
您可以通過如下方法最佳化分析語句。
盡量避免產生字串的操作。
例如使用date_format函數產生格式化的時間戳記,導致查詢效率低。針對時間戳記的計算,建議使用date_trunc或者time_series函數進行計算。樣本如下:
* | select date_format(from_unixtime(__time__) , '%H_%i') as t, count(1) group by t
盡量避免對字串列進行分組統計。
使用GROUP BY文法基於字串列進行分組統計,會導致大量的Hash計算,這部分計算量佔據整體計算量的50%以上。樣本如下:
查詢和分析語句(速度快)
* | select count(1) as pv , from_unixtime(__time__-__time__%3600) as time group by __time__-__time__%3600
查詢和分析語句(速度慢)
* | select count(1) as pv , date_trunc('hour',__time__) as time group by time
上述兩條查詢分析語句都是計算每小時的日誌條數。第二條語句先把時間戳記轉化成字串格式(例如2021-12-12 00:00:00),然後對這個字串列進行分組統計。第一條語句對時間整點值進行計算,並且通過分組統計後再將時間戳記轉化為字串格式。
基於多列進行分組統計時,把字典大的欄位放在前面。
例如欄位的值有13個,uid欄位的值有1億個,則建議在GROUP BY子句中將uid欄位放在前面。樣本如下:
查詢和分析語句(速度快)
* | select province,uid,count(1) group by uid,province
查詢和分析語句(速度慢)
* | select province,uid,count(1) group by province,uid
使用估算函數。
估算函數的效能比精算函數的好。估算會損失一定的精確度,用於達到快速計算的效果。樣本如下:
查詢和分析語句(速度快)
* |select approx_distinct(ip)
查詢和分析語句(速度慢)
* | select count(distinct(ip))
在SQL分析語句中指定擷取需要的列,盡量不要讀取所有列。
在SQL分析語句中,盡量唯讀取需要參與計算的列。如果要擷取所有列,請使用查詢文法。樣本如下:
查詢和分析語句(速度快)
* |select a,b c
查詢和分析語句(速度慢)
* |select *
不是用於分組的列,盡量放在彙總函式中。
例如userid與使用者名稱必定是一一對應的,您只需使用GROUP BY文法對userid進行分組統計即可。樣本如下:
查詢和分析語句(速度快)
* | select userid, arbitrary(username), count(1) group by userid
查詢和分析語句(速度慢)
* | select userid, username, count(1) group by userid,username
盡量避免使用IN文法
盡量避免在分析語句中使用IN文法,您可以在查詢語句中使用OR文法代替。樣本如下:
查詢和分析語句(速度快)
key: a or key: b or key: c | select count(1)
查詢和分析語句(速度慢)
* | select count(1) where key in ('a','b')