elasticsearch,为什么prefix性能消耗很大

推荐公众号

程序员探索之路

索引准备

索引mapping
PUT student
{
  "mappings": {
    "properties": {
      "name":{
        "type": "keyword"
      },
      "age":{
        "type": "integer"
      }
    }
  }
}

数据
PUT /student/doc/1
{ "name": "王-a" }


PUT /student/doc/2
{ "name": "王-b" }


PUT /student/doc/3
{ "name": "王-c" }


PUT /student/doc/4
{ "name": "王二a" }
。。。。。。。

查询条件
GET /studeng/_doc/_search
{
    "query": {
        "prefix": {
            "name": "王-"
        }
    }
}

查询过程

name字段是keyword类型 不进行分词,每个name还是以它们精确值的方式存在于每个文档的索引中倒排索引中
在倒排索引中如下示例:

Termdoc ids
王一a1
王一b2
王一c3
王二a4
为了支持前缀匹配,查询会做以下事情:
  1. 扫描词列表并查找到第一个以 王- 开始的词。
  2. 搜集关联的文档 ID 。
  3. 移动到下一个词。
  4. 如果这个词也是以 王-开头,查询跳回到第二步再重复执行,直到下一个词不以 王-为止。

这对于小的例子当然可以正常工作,但是如果倒排索引中有数以百万的邮编都是以王-开头时,前缀查询则需要访问每个词然后计算结果!
前缀越短所需访问的词越多。如果我们要以 王作为前缀而不是 王一 ,那么就可能需要做千万次的匹配。

wildcard 和 regexp

wildcard(通配符查询) 和 regexp(正则查询) 查询的工作方式与 prefix 查询完全一样,它们也需要扫描倒排索引中的词列表才能找到所有匹配的词,然后依次获取每个词相关的文档 ID ,与 prefix 查询的唯一不同是:它们能支持更为复杂的匹配模式。
这也意味着需要同样注意前缀查询存在性能问题,对有很多唯一词的字段执行这些查询可能会消耗非常多的资源,所以要避免使用左通配这样的模式匹配(如: *foo 或 .*foo 这样的正则式)。

参考文章

https://www.elastic.co/guide/cn/elasticsearch/guide/current/prefix-query.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值