您可以使用以下方式,提高日志查詢分析的速度。
增加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')