随着我的ES索引/群集规模扩大(现在约20亿个文档),我注意到了更显着的性能损失。所以我开始搞乱我的查询,看看我是否可以从中挤出一些信息。
当我这样做时,我注意到当我在我的过滤器中使用布尔查询时,我的结果将需要大约3.5-4秒才能返回。但是,如果我在查询中执行相同的操作,则更像是10-20ms
以下是2个查询:
使用过滤器
POST /backup/entity/_search?routing=39cd0b95-efc3-4eee-93d1-93e6f5837d6b
{
"query": {"bool":{"should":[],"must":[{"match_all":{}}]}},
"filter": {
"bool": {
"must": [
{
"term": {
"serviceId": "39cd0b95-efc3-4eee-93d1-93e6f5837d6b"
}
},
{
"term": {
"subscriptionId": "3eb5021e-2f1d-4292-9fd5-95788ebfafa0"
}
},
{
"term": {
"subscriptionType": 0
}
},
{
"terms": {
"entityType": [
"4"
]
}
}
]
}
}
}
使用查询
POST /backup/entity/_search?routing=39cd0b95-efc3-4eee-93d1-93e6f5837d6b
{
"query": {"bool":{"should":[],"must":[
{
"term": {
"serviceId": "39cd0b95-efc3-4eee-93d1-93e6f5837d6b"
}
},
{
"term": {
"subscriptionId": "3eb5021e-2f1d-4292-9fd5-95788ebfafa0"
}
},
{
"term": {
"subscriptionType": 0
}
},
{
"terms": {
"entityType": [
"4"
]
}
}
]}}
}
就像我说的那样,我根本不使用Filter的第二种方法只花了几毫秒,而第一种查询花了将近4秒。这似乎与文档所说的完全相反。他们说Filter实际上应该非常快,而Query应该是需要更长时间的查询。那么为什么我在这看到完全相反的呢?
可能是我的索引映射吗?如果有人知道为什么会这样,我很乐意听取建议。
由于
答案 0 :(得分:1)
根filter
元素实际上是another name for post_filter
element。不知怎的,it was supposed to be removed (the filter
) in ES 1.1但是它已经滑落并存在于2.x版本中。
虽然在ES 5中完全删除了。
因此,您的第一个查询不是"过滤器"查询。它是一个查询,其结果在聚合后使用(如果适用),然后post_filter
/ filter
应用于结果。所以你基本上有两个步骤:https://www.elastic.co/guide/en/elasticsearch/reference/1.5/search-request-post-filter.html
有关其效果的更多信息here:
虽然我们已经获得了标签过滤器的可缓存性,但我们可能会显着增加评分成本。当您需要未经过滤的聚合时,后期过滤器非常有用,但需要过滤。如果您没有构面或聚合,则不应使用post_filter(或其已弃用的顶级同义词过滤器)。
正确的过滤查询如下:
{
"query": {
"filtered": {
"query": {
"bool": {
"should": [],
"must": [
{
"match_all": {}
}
]
}
},
"filter": {
"bool": {
"must": [
{
"term": {
"serviceId": "39cd0b95-efc3-4eee-93d1-93e6f5837d6b"
}
},
{
"term": {
"subscriptionId": "3eb5021e-2f1d-4292-9fd5-95788ebfafa0"
}
},
{
"term": {
"subscriptionType": 0
}
},
{
"terms": {
"entityType": [
"4"
]
}
}
]
}
}
}
}
}
答案 1 :(得分:-1)
过滤器 更快。您的问题是您在过滤器案例中包含match_all
查询。这匹配所有 20亿个文档。然后必须对过滤器进行设置操作以剔除该组。省略过滤器测试中的query
部分,您会发现结果更快。