performance - Elasticsearch:最佳性能的过滤器顺序

标签 performance elasticsearch

Elasticsearch 指南说

"Each filter is calculated and cached independently, regardless of where it is used. If two different queries use the same filter, the same filter bitset will be reused. Likewise, if a single query uses the same filter in multiple places, only one bitset is calculated and then reused." (https://www.elastic.co/guide/en/elasticsearch/guide/current/filter-caching.html)



在另一页上还说:

"The order of filters in a bool clause is important for performance. More-specific filters should be placed before less-specific filters in order to exclude as many documents as possible, as early as possible. If Clause A could match 10 million documents, and Clause B could match only 100 documents, then Clause B should be placed before Clause A." (https://www.elastic.co/guide/en/elasticsearch/guide/current/_filter_order.html)



我不太明白当每个过滤器被独立缓存时,bool 子句中过滤器的顺序是多么重要。

我会想象从缓存中执行或检索子句 B,从缓存中执行或检索子句 A,然后“合并”过滤器位集。为什么顺序很重要?

最佳答案

这个指导有点误导。它更复杂,很难尝试编写一套适合所有情况的规则。随着数据的变化,规则也在变化。随着查询和过滤器类型的变化,规则也会发生变化。特定过滤器的执行速度可能比广泛的过滤器要慢,因为规则发生了变化。在每个段的基础上,过滤器的结果大小可能与另一个段相反,它并不总是可预测的。因此,首先您必须了解更多内部结构,然后在进入现代 Elasticsearch 2.x 时,您需要放弃试图控制它。

注意:您的第二个报价(过滤器顺序)和相关链接指向一个页面,该页面被认为是 Elasticsearch 2.x 的“过时”页面,稍后会更新。因此,该建议可能适用于也可能不适用于现代。

回顾一下 Elasticsearch 1.x 以及下单建议的原因:

让我们先谈谈过滤器在内存中是如何表示的。它们要么是匹配文档的迭代列表,要么是随机访问“它在这里”模型。根据过滤器的类型,取决于哪个更有效。现在如果所有东西都被缓存了,你只是将它们相交,成本会因大小和类型而异。

如果过滤器未缓存,但可缓存,则过滤器将独立执行,并且先前的过滤器仅会受到交集总成本的影响。

如果过滤器不可缓存,那么它可以由先前的结果引导。想象一个 Query加一个 Filter .如果您执行查询,并在应用过滤器之后,如果过滤器限制为非常小的记录集,您将做很多额外的工作。您在查询中浪费了收集、评分和整体构建大量结果的时间。但是如果你转换成 FilteredQuery并同时进行,然后 Query忽略已被 Filter 消除的所有记录.它只需要考虑已经在使用的相同文档。这称为“跳过”。并非所有过滤器类型都利用跳过,但有些可以。这就是为什么较小的“引导”过滤器会让其他人更快地使用它。

除非您知道每个过滤器类型、数据的启发式以及每个特定过滤器将如何受到这些过滤器的影响,否则您没有足够的信息,只能说“首先放置最有限制的过滤器,然后放置较大的过滤器”和希望它奏效。对于 bool默认情况下不缓存其整体结果,因此您必须注意其重复性能(和/或缓存它)。当滤波器交叉点的一侧较小时,效率更高。所以从一个小的开始会让所有其他的交叉点更快,因为它们只会变得更小。如果是 bool查询而不是过滤器进行评分,避免评分超过必要的文档更为重要。

另一个重要的注意事项是“最具体的过滤器优先”有时可能会很慢(脚本过滤器或其他),因此它应该真正阅读:“最低成本,最具体的过滤器优先”。

Elasticsearch 2.0, things will change :

It’s time to forget everything you knew about queries and filters: Elasticsearch 2.0 will make much better decisions by itself instead of relying on users to formulate an optimized query.



在 2.x 中,你应该尽量少玩系统,让引擎做出最好的选择。引擎实际上可能会在引擎盖下得到一些完全不同的东西,一个重写的过滤器,一个内部结构和数据的完全改变。你甚至可能不再控制缓存。所以你需要阅读更多相关信息。

The previous filter API could be consumed in two ways: either using iterators over matching documents, or using an optional random-access API that allowed to check if a particular document matched the filter or not. Everything is good so far, except that the best way to consume a filter depended on which kind of filter you had: for instance the script filter was more efficient when using the random-access API while the bool filter was more efficient using the iterator API. This was quite a nightmare to optimize and was the root cause why the bool filter on the one hand and the and and or filters on the other hand performed differently.



引擎现在将考虑更多因素来决定什么是最好的,包括评分、结果大小的估计、与相关过滤器相交的最佳方式,甚至可能是在每个分割市场的基础上,等等。

此外,这篇文章明确指出,即使缓存也可能会产生误导,但它并不总是能让事情变得更快。有时内部数据结构在最初使用时比总是缓存的位集结构更好。因此,在 2.x 中,这也发生了变化,以避免缓存从 native 数据结构中执行得更好的内容,而根本不缓存。

在博文中 Roaring Bitmaps更多详情:

Clearly the most important requirement is to have something fast: if your cached filter is slower than executing the filter again, it is not only consuming memory but also making your queries slower. The more sophisticated an encoding is, the more likely it is to slow down encoding and decoding because of the increased CPU usage



在这里你会得到很多关于内部数据结构、缓存、交集以及更多关于2.x内部变化的信息,这将帮助你更深入地理解过滤器性能。

While it may surprise you if you are new to search engine internals, one of the most important building blocks of a search engine is the ability to efficiently compress and quickly decode sorted lists of integers.



从这最后几个 2.x 博客链接中,您对您的问题有很多背景知识,它们讨论了您尝试使用过滤器排序解决的所有问题。信息和细节都在那里,您可以更好地了解 1.x 与 2.x 以及如何解决查询+过滤器。所以请记住:

There is no particular implementation which is constantly better than all others.



另请参阅这些 1.x 资源作为历史引用:
  • Optimizing Elasticsearch searches涵盖更多关于过滤器排序的内容。它总结说:

    That said, you still need to think about which order you filter in. You want the more selective filters to run first. Say you filter on type: book and tag: elasticsearch. If you have 30 million documents, 10 million of type book and only 10 tagged Elasticsearch, you’ll want to apply the tag filter first. It reduces the number of documents much more than the book filter does.

  • All About Elasticsearch Filter Bitsets被认为是现代过时的文章,但它提供了有关您引用的过滤器订购文档的更多背景信息。
  • A forum answer by Martijn v Groningen似乎对 bool 说反了对比 and关于使用迭代与随机访问的查询,但每个人的想法都是相同的:通过限制过滤器列表中较早的文档来确保安全——无论哪种模型适用于一种类型和另一种类型。
  • 关于performance - Elasticsearch:最佳性能的过滤器顺序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34727193/

    相关文章:

    algorithm - 具有非递减数字的最大数

    elasticsearch - 缓冲区刷新花费的时间比slow_flush_log_threshold长

    csv - 无法使用Logstash解析CSV文件

    java - 如何设置日期格式以插入 Elasticsearch

    performance - 有关使Hive在Hadoop上更快运行的任何技巧?

    AngularJS 初始加载时间优化

    linux - Linux 中的高性能数据包处理

    javascript - javascript 中的属性与常量访问

    elasticsearch - Elasticsearch集群上的刷新时间跳跃

    ruby-on-rails - ElasticSearch +仅在id字段上进行轮胎搜索