介绍优化查询的方法,可以帮助用户提高查询效率。主要包括以下方法:
  • 增加更多shard。
  • 缩短时间范围和数据量。
  • 多次重复查询。
  • 优化查询的SQL。

增加更多shard

shard代表的是计算资源,shard越多,计算越快。保证平均每个shard扫描的数据不多于5000万条日志。 增加shard可以通过分裂shard完成。
说明 分裂shard后,会产生更多费用,且只对新数据起到加速效果,旧数据仍然在旧的shard上。

缩减查询的时间范围和数据量

  • 时间范围越大,查询越慢。如果您查询1年的时间,或者查询1个月的时间。 计算是按天完成的,所以,适当的缩短时间可以更快完成计算。
  • 数据量越大,查询越慢。请尽量减少查询的数据量。

多次重复查询

当查询不精确时,可以尝试多次重复查询。每次查询时,底层加速机制会充分利用已有的结果进行分析。所以,多次查询可以使结果更加精确。

优化query

计算时间较长的查询语句特点:
  • 对字符串列进行group by。
  • 对多列(大于5列)字段进行group by。
  • 在SQL中有生成字符串的操作。
为了优化query,有以下方法:
  • 尽量避免生成字符串的操作
    • 使用date_format函数生成格式化的时间戳,导致查询效率低下。
      * | select date_format(from_unixtime(__time__) , '%H_%i') as t, count(1) group by t
    • 使用substr生成字符串。 对于这类时间戳函数,建议使用date_trunc或者time_series函数进行分析。
  • 尽量避免对字符串列进行GROUP BY计算
    对字符串进行GROUP BY,会导致大量的hash计算,这部分计算量往往会占据整体计算的50%以上。例如:
    * | 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 和Query 2都是计算每小时的日志count数,但是Query 1 首先把时间转化成字符串,例如2017-12-12 00:00:00, 然后对这个字符串进行GROUP BY。 Query 2是先对时间整点值进行计算,GROUP BY计算后才会转化成字符串类型。所以在执行效率上,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
  • 避免使用in语法
    尽量避免在SQL中使用in语法,而应该把in语法用搜索的or语法代替。
    快:key : a or key :b or key:c | select count(1)
    慢:* | select count(1) where key in ('a','b')