Elasticsearch 中为什么选择倒排索引而不选择 B 树索引

前言

索引可能大家都不陌生,在用关系型数据库时,一些频繁用作查询条件的字段我们都会去建立索引来提升查询效率。在关系型数据库中,我们一般都采用 B 树索引进行存储,所以 B 树索引也是我们接触比较多的一种索引数据结构,然而在 es 中,进行全文搜索的时候却并没有选择使用 B 树 索引,而是采用的倒排索引。本文就让我们来看看 es 中的倒排索引是如何存储和检索的吧。

为什么全文索引不使用 B+ 树进行存储

关系型数据库,如 MySQL,其选择的是 B+ 树索引,如下图就是一颗简单的的 B+ 树示例:
请添加图片描述
上图中蓝色的表示索引值,白色的表示指针,最底层叶子节点除了存储索引值还会存储整条数据(InnoDB 引擎),而根节点和枝节点不会存储数据,B+ 树之所以这么设计就是为了使得根节点和枝节点能够存储更多的节点,因为搜索的时候从根节点开始搜索,每查询一个节点就是一次 IO 操作,所以一个节点能存储更多的索引值能减少磁盘 IO 次数。

那么到这里我们就可以思考这个问题了,假如索引值本身就很大,那么 B+ 树是不是性能会急剧下降呢?答案是肯定的,因为当索引值很大的话,一个节点能存储的数据会大大减少(一个节点默认是 16kb 大小),B+ 树就会变得更深,每次查询数据所需要的 IO 次数也会更多。而且全文索引就是需要支持对大文本进行索引的,从空间上来说 B+ 树不适合作为全文索引,同时 B+ 树因为每次搜索都是从根节点开始往下搜索,所以会遵循最左匹配原则,而我们使用全文搜索时,往往不会遵循最左匹配原则,所以可能会导致索引失效。

总结起来 B+ 树不适合作为全文搜索索引主要有以下两个原因:

  • 全文索引的文本字段通常会比较长,索引值本身会占用较大空间,从而会加大 B+ 树的深度,影响查询效率。
  • 全文索引往往需要全文搜索,不遵循最左匹配原则,使用 B+ 树可能导致索引失效。

全文检索

在全文检索当中,我们需要对文档进行切词处理,切好之后再将切出来的词和文档进行关联,并进行索引,那么这时候我们应该如何存储关键字和文档的对应关系呢?

正排索引

可能大家都知道,在全文检索中(比如:Elasticsearch)用的是倒排索引,那么既然有倒排索引,自然就有正排索引。

正排索引又称之为前向索引(forward index)。我们以一篇文档为例,那么正排索引可以理解成他是用文档 id 作为索引关键字,同时记录了这篇文档中有哪些词(经过分词器处理),每个词出现的次数已经每个词在文档中的位置。

但是我们平常在搜索的时候,都是输入一个词然后要得到文档,所以很显然,正排索引并不适合于做这种查询,所以一般我们的全文检索用的都是倒排索引,但是倒排索引却并不适合用于聚合运算,所以其实在 es 中的聚合运算用的是正排索引。

倒排索引

倒排索引又称之为反向索引(inverted index)。和正排索引相反,倒排索引使用的是词来作为索引关键字,并同时记录了哪些文档中有这个词。

在这里我们以一个英文文档为例子,之所以选择用英文文档是因为英文分词比较简单,直接以空格进行分词即可,而中文分词相对比较复杂。

我们以 Elasticsearch 官网中下面两句话作为两位文档来分析:

Elasticsearch is the distributed search and analytics engine at the heart of the Elastic Stack.
Elasticsearch provides near real-time search and analytics for all types of data.

根据上面两句话,假设我们可以得到下面这样的一个索引结构:
请添加图片描述

其中:
  • term index:顾名思议
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值