弹性搜索过滤器的执行速度比查询慢

时间:2016-07-26 19:58:08

标签: elasticsearch

随着我的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应该是需要更长时间的查询。那么为什么我在这看到完全相反的呢?

可能是我的索引映射吗?如果有人知道为什么会这样,我很乐意听取建议。

由于

2 个答案:

答案 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部分,您会发现结果更快。