我希望对我最近观察到的弹性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适用于字符串类型,但不适用于长类型?是因为数字字段根本不需要全局序数吗?
由于
答案 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,你会看到:
execution_hint
被完全忽略,这应该可以回答您的问题。