术语聚合性能高基数

时间:2015-08-02 07:50:00

标签: performance elasticsearch cardinality

我希望对我最近观察到的弹性1.5.2中的查询性能做一些澄清。

我有一个高基数的字符串字段(大约200,000,000)。 我观察到,如果我使用简单的术语聚合与执行提示global_ordinals_low_cardinality,会发生两件事: 1.查询返回与global_ordinals或global_ordinals_hash相同的结果。 2.查询执行得更快。 (大约是global_ordinals的两倍,是global_ordinals_hash的4倍。

以下是查询:

{
   "aggs": {
      "myTerms": {
         "terms": {
            "field": "myField",
            "size": 1000,
            "shard_size": 1000,
            "execution_hint": "global_ordinals_low_cardinality"
         }
      }
   }
}

我不明白为什么在这种情况下使用global_ordinals_low_cardinality甚至合法,因为我的字段具有很高的基数。所以也许我不明白global_ordinals_low_cardinality究竟是什么意思?

其次,我有另一个数字字段(长),具有大致相同的基数值。 对于从上面开始的相同字符串字段,长字段的值实际上是预先计算的哈希值(murmur3),我用它来大大加速基数聚合。 在数字字段上运行相同的术语聚合执行与global_ordinals_hash一样糟糕。 事实上,我使用的执行提示无关紧要,执行时间保持不变。

那么为什么global_ordinals_low_cardinality适用于字符串类型,但不适用于长类型?是因为数字字段根本不需要全局序数吗?

由于

1 个答案:

答案 0 :(得分:0)

我认为official documentation和源代码都对此有所了解。首先,需要提及的一件事是execution_hint正是它的名字所说的,即只是一个提示 ES将试图兑现,但在所有情况下可能都不会认为不合适。

因此,事实上你有一个高基数字段会排除使用global_ordinals_low_cardinality,因为:

  

global_ordinals_low_cardinality仅在低基数字段上默认启用。

对于global_ordinals_hash,它主要用于内部术语聚合(此处不是这种情况),map仅用于在脚本上运行聚合而少数文档与查询匹配时使用(不是cas)或者

因此,它为您提供了一个选项,即global_ordinals,这是在顶级字词聚合中使用的默认提示。

如前所述,execution_hint只是您指定的提示,但无论如何,ES都会尽力为您的数据选择正确的执行模式。查看源代码是有启发性的,并且对一些事情有所了解:

Starting here,你会看到:

  1. on line 201,您的提示已被阅读,如果该字段不支持全局序数(lines 205-241
  2. ,则可能会被覆盖
  3. 如果您的field is numericexecution_hint被完全忽略,这应该可以回答您的问题。