不同的query在分析时的效率是不同的,在此为您提供部分常见的优化query方式,供您参考。

尽量避免对字符串列进行GROUP BY计算

对字符串进行GROUP BY,会导致大量的hash计算,这部分计算量往往会占据整体计算的50%以上。

例如以下两个query:

* | select count(1) as pv , date_trunc('hour',__time__) as time group by time
* | select count(1) as pv , from_unixtime(__time__-__time__%3600) as time group by __time__-__time__%3600

Query 1 和2达到的效果是相同的,都是计算每个小时的日志count数,但是Query 1 首先把时间转化成字符串,例如2017-12-12 00:00:00, 然后对这个字符串进行GROUP BY。 Query 2是先对时间整点值进行计算,GROUP BY计算后才会转化成字符串类型。Query 1需要对字符串进行hash操作,所以在执行效率上,Query 2更佳。

GROUP BY多列时,把字典大的字段放在前面

例如,province有13个,用户有1亿。

快:  * | select province,uid,count(1)groupby province,uid
慢:   * | select province,uid,count(1)groupby uid,province

使用估算函数

估算函数的性能要比精确计算好很多。估算会损失一些可接受的精确度,来达到快速计算的效果。

快: * |select approx_distinct(ip)
慢:  * | select count(distinct(ip))

在SQL中获取需要的列,尽量不要读取所有列

获取所有列,请使用查询语法。在SQL计算时,尽量只读取需要参与计算的列,这会加快计算。

快 : * |select a,b c 
慢 :* |select*

非group by的列,尽量放到聚合函数中

例如,userid,用户名,必定是一一对应的,我们只需要按照userid进行group by即可。

快: * | select userid, arbitrary(username), count(1)groupby userid
慢:  * | select userid, username, count(1)groupby userid,username