Elasticsearch指南说
"每个过滤器都是独立计算和缓存的,无论它在何处使用.如果两个不同的查询使用相同的过滤器,则将重用相同的过滤器位集.同样,如果单个查询在多个位置使用相同的过滤器,则只有一个位集计算然后重复使用." (https://www.elastic.co/guide/en/elasticsearch/guide/current/filter-caching.html)
在另一页上它还说:
"bool子句中的过滤器顺序对于性能很重要.更具体的过滤器应该放在不太具体的过滤器之前,以尽可能多地排除尽可能多的文档.如果条款A可以匹配1000万个文档,条款B只能匹配100份文件,则条款B应放在条款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
加号a Filter
.如果执行查询,并且在应用过滤器之后,如果过滤器限制为非常小的记录集,则会执行大量额外工作.您在查询中浪费了时间,收集,评分和整体构建了大量结果.但是如果你转换为a FilteredQuery
并同时执行这两个操作,那么Query
忽略已经被删除的所有记录Filter
.它只需要考虑已经在使用的相同文档.这称为"跳过".并非所有过滤器类型都利用跳过,但有些可以.这就是为什么较小的"引导"过滤器会让其他人更快地使用它.
除非您了解每种过滤器类型,数据的启发式以及每种特定过滤器将如何受到这些过滤器的影响,否则除了说"首先放置大多数限制过滤器,第二次放置更大的过滤器"之外,您没有足够的信息,希望它成功.因为bool
默认情况下不会缓存其整体结果,因此您必须注意其重复性能(和/或缓存它).当滤波器交叉点的一侧很小时,它更有效.所以有一个小的开始使所有其他交叉点更快,因为它们只能变小.如果它是一个bool
查询而不是过滤器进行评分,那么避免评分超过必要的文档更为重要.
另一个重要的注意事项是"最具体的过滤器优先"有时可能很慢(脚本过滤器或其他),因此它应该真正读取:"最低成本,最先特定的过滤器".
使用Elasticsearch 2.0,事情会发生变化:
现在是时候忘记你对查询和过滤器的了解:Elasticsearch 2.0将自己做出更好的决策,而不是依靠用户来制定优化的查询.
在2.x中你应该少尝试游戏系统,让引擎做出最好的选择.发动机实际上最终可能会有一些完全不同的东西,一个重写的过滤器,内部结构和数据的完全变化.你甚至可能不再控制缓存了.所以你需要阅读更多相关信息.
可以通过两种方式使用先前的过滤器API:使用迭代器而不是匹配文档,或者使用可选的随机访问API,以允许检查特定文档是否与过滤器匹配.到目前为止,一切都很好,除了使用过滤器的最佳方式取决于您使用哪种过滤器:例如,
script
使用随机访问API时bool
过滤器更有效,而过滤器使用迭代器API更有效.这对于优化来说是一场噩梦,并且是bool
一方面过滤器and
和另一方面or
过滤器和过滤器执行不同的根本原因.
引擎现在将决定考虑更多因素的最佳因素,包括评分,结果大小的估计,相交过滤器的最佳交叉方式,甚至可能基于每个细分,等等.
此外,本文还清楚地表明即使缓存也可能会产生误导,但并不总能让事情变得更快.有时内部数据结构在最初使用时比总是缓存的bitset结构更好.因此,在2.x中,这也是为了避免缓存从本机数据结构中执行得更好而没有缓存的事情.
在博客文章中,Roaring Bitmaps有更多细节:
显然,最重要的要求是快速运行:如果缓存的过滤器比再次执行过滤器慢,那么它不仅会消耗内存,还会使查询变慢.编码越复杂,由于CPU使用率的增加,越有可能减慢编码和解码速度
在这里,您可以获得有关内部数据结构,缓存,交集以及2.x内部更改的更多信息,这将有助于您更深入地了解过滤器性能.
虽然如果您是搜索引擎内部的新手,可能会让您大吃一惊,但搜索引擎最重要的构建模块之一就是能够有效地压缩和快速解码排序的整数列表.
从最后几个2.x博客链接中,您有很多关于您的问题的背景知识,他们讨论了您尝试使用过滤器排序的所有问题.信息和详细信息都在那里,您可以更好地理解1.x与2.x以及如何解决查询+过滤器.所以请记住:
没有特别的实施方式总是比其他实施方式更好.
另请参阅这些1.x资源以获取历史参考:
优化Elasticsearch搜索涵盖了有关过滤器排序的更多信息.它总结说:
也就是说,您仍然需要考虑过滤哪个顺序.您希望首先运行更具选择性的过滤器.假设您按类型过滤:book和tag:elasticsearch.如果您有3000万个文档,1000万个类型书和10个标记的Elasticsearch,您将首先应用标记过滤器.它比书籍过滤器减少了更多的文档数量.
所有关于Elasticsearch过滤器比特集都被认为是现代的过时文章,但它提供了有关您引用的过滤器订购文档的更多背景信息.
Martijn v Groningen的论坛答案似乎bool
与and
使用迭代与随机访问的查询相反,但每个人的想法是相同的:通过限制过滤器列表中较早的文档来安全 - 无论哪个模型是一种类型与另一种类型.