如何在elasticsearch中优化聚合查询

时间:2016-06-04 07:52:28

标签: elasticsearch

现在我正在使用ES进行聚合。基本逻辑可以表示为

select count(*)
from 
(select key, count(*) from table where *** 

按键分组(*)> C )z 这里过滤条件由最终用户指定,这意味着我不能做任何前期工作。 我已经使用桶选择器实现了逻辑。

但是在我的情况下,通常有数百万个不同的密钥,这意味着ES返回了数百万个桶,默认情况下按doc_count排序。这非常耗时。我不知道是否有一些策略可以加速查询,例如关闭排序。

1 个答案:

答案 0 :(得分:1)

如果我理解正确,您的查询会执行以下操作:

  1. key
  2. 对所有条目进行分组
  3. 删除count <= c
  4. 所有分组的条目
  5. 计算所有剩余的分组条目
  6. 然后SELECT key, count(*)没用,因为它永远不会被再次使用。您只需使用SELECT 1

    即可

    此查询根本不需要排序。

    基本上有3种加速查询的方法:

    1. 获取更多服务器!在多个节点上,ES可以轻松地并行执行此聚合。

    2. 请勿在需要时聚合数据,而是使用每天执行一次的后台任务。此后台任务基本上会创建相同的数据,如下面STORE 2中所示。当然,通过这种方式,您将始终必须提供旧数据,但这会加快速度!

    3. 预先聚合您的数据!使用一些简单的键值存储(或者甚至只是坚持使用ES进行此操作),然后执行以下操作:

      • 插入新文档时:获取其密钥,然后递增该编号。

      • 当文档被删除时:获取其密钥,并递减计数器。

    4. 然后你基本上有2个商店:1个用于实际文件,1个用于汇总数据,即

      STORE 1:
      [
        {id: 1, key: foo, ...},
        {id: 2, key: foo, ...},
        {id: 3, key: bar, ...},
        {id: 4, key: baz, ...}
      ]
      
      STORE 2:
      [
        {id: foo, counter: 2},
        {id: bar, counter: 1},
        {id: baz, counter: 1}
      ]
      

      这样,您可以在插入/删除STORE 1中的文档时进行聚合。插入/删除时,这当然更耗时,因为每次都必须触摸2个数据存储。

      但现在您可以简单地计算STORE 2中的条目以获得结果。这将大大提高此操作的查询性能。

      你看:这总是一个权衡。你必须决定你需要什么:

      1. 实时数据+高插入/删除性能+慢速聚合

      2. 非实时数据+高插入/删除性能+快速聚合

      3. 实时数据+慢插入/删除+快速聚合