正排索引

简介: 介绍ElasticSearch相关正排索引

1. 正排索引

正排索引: 正排索引是指文档ID为key,表中记录每个关键词出现的次数,查找时扫描表中的每个文档中字的信息,直到找到所有包含查询关键字的文档。

网页A中的内容片段:  

Tom is a boy.     Tom is a student too.

正排索引如下:

内容 Tom is a boy Tom is a student too
分词 Tom is a boy student too
  • 正排索引
Index Word word_hit(词出现的次数) word_offset(词出现的位置)
TA Tom 2 1,5
is 2 2,6
a 2 3,7
boy 1 4
student 1 8
too 1 9

出现的位置进行差分序列

Index word word_hit(词出现的次数) word_offset(词出现的位置)
docid Tom 2 1,4
is 2 2,4
a 2 3,4
boy 1 4
student 1 8
too 1 9
  • 根据位置还原字符串
1 2 3 4 5 6 7 8 9
Tom Tom
is is
a a
boy
student
too

从上面的介绍可以看出,正排是以 docid 作为索引的,但是在搜索的时候我们基本上都是用关键词来搜索。


所以,试想一下,我们搜一个关键字(Tom),当100个网页的10个网页含有Tom这个关键字。但是由于是正排是doc id 作为索引的,所以我们不得不把100个网页都扫描一遍,然后找出其中含有Tom的10个网页。然后再进行rank,sort等。效率就比较低了。尤其当现在网络上的网页数已经远远超过亿这个数量后,这种方式现在并不适合作为搜索的依赖。


不过与之相比的是,正排这种模式容易维护。由于是采用doc 作为key来存储的,所以新增网页的时候,只要在末尾新增一个key,然后把词、词出现的频率和位置信息分析完成后就可以使用了。 所有正排的优点是:易维护;缺点是搜索的耗时太长;

2. 生成时间

正排索引在PUT/POST操作的时候就会生成。

3.核心原理

正排索引,也会写入磁盘文件中,然后会进入os cache中进行缓存,以提升正排索引的性能。如果os cache内存大小不足够放得下整个正排索引,就会将正排索引的数据写入磁盘文件中去。

4. 性能问题

ES官方建议,ES是大量基于os cache来进行缓存和提升性能的,不建议使用jvm内存来进行缓存,那样会导致一定的GC开销和OOM问题,所以应该给jvm更少的内存,给os cache更大的内存,这样可以大容量的os cache可以提升doc value和倒排索引的缓存和查询效率。 一般64G内存的服务器的,最多给jvm16G内存,将剩余的几十G都给os cache。

5. 存储压缩

正排索引的value在保存之前会做相应的处理,然后再来保存进去正排索引,以节省空间。具体策略如下:

(1)所有值相同,直接保留单值。

(2)少于256个值,使用table encoding模式的压缩方式处理。

(3)大于256个值,看有没有最大公约数,有就除以最大公约数,然后保留这个最大公约数和商。

(4)如果没有最大公约数,采取offset节后压缩的方式。

6. 禁用

如果的确不需要doc value,比如聚合等操作,那么可以禁用,减少磁盘空间占用。

{
  "mappings": {
    "my_type": {
      "properties": {
        "my_field": {
          "type":       "keyword"
          "doc_values": false 
        }
      }
    }
  }
}

7. 使用

聚合分析使用了倒排索引+正排索引(doc value)。

只使用倒排索引存在的问题:

如存在数据如下:

id province latency timestamp
1 江苏 68 2016-10-28
2 江苏 76 2016-10-29
3 江苏 83 2016-10-29
4 新疆 654 2016-10-28
5 江苏 105 2016-10-29
6 新疆 101 2016-10-28
7 新疆 302 2016-10-29
8 江苏 76 2016-10-28

进行如下聚合分析: 查询province为江苏的所有latency的分组数量。查询参数如下:

{
  "size":0,
  "query": {
    "match": {
      "province": "江苏"
    }
  },
  "aggs": {
    "group_by_province": {
      "terms": {
        "field": "latency"
      }
    }
  }
}

如果只使用倒排索引进行查询,则查找过程如下: 江苏 -> 1,2,3,5,8 新疆 -> 4,6,7


第一步:根据倒排索引province字段查询,得到了其对应的文档为1,2,3,5,8。


第二步:根据latency字段的值进行分组。但是这时候我们只知道我们要找的文档为1,2,3,5,8。但是文档1,2,3,5,8当中有哪些latency,我们是无法得到的。此时只能扫描整个倒排索引,根据latency的值获取到对应的文档,看本文档是否在1,2,3,5,8之中,

使用倒排索引+正排索引 首先使用倒排索引进行查询,则查找过程如下: 江苏 -> 1,2,3,5,8 新疆 -> 4,6,7

第一步:根据倒排索引province字段查询,得到了其对应的文档为1,2,3,5,8。

正排索引如下: doc1 ->江苏 68 2016-10-28 doc2 ->江苏 76 2016-10-29 ...... 这时候


第二步就不需要扫描整个倒排索引,直接使用正排索引,在文档1,2,3,5,8之中查询统计即可。

相关文章
|
索引
索引
索引。
81 0
|
2月前
|
存储 关系型数据库 数据库
什么是索引
【10月更文挑战第15天】什么是索引
|
4月前
|
TensorFlow 算法框架/工具 索引
索引
【8月更文挑战第13天】索引。
30 1
|
7月前
|
SQL 搜索推荐 关系型数据库
|
7月前
|
SQL 关系型数据库 MySQL
关于索引的使用
关于索引的使用
|
7月前
|
安全 关系型数据库 MySQL
合理使用索引
【5月更文挑战第9天】这篇文章探讨了数据库索引的高效使用,包括函数和表达式索引、查找和删除未使用的索引、安全删除索引、多列索引策略、部分索引以及针对通配符搜索、排序、散列和降序索引的特殊技巧。还介绍了部分索引在减少索引大小和处理唯一性约束中的应用,以及PostgreSQL对前导通配符搜索的支持。通过遵循简单的多列索引规则和利用特定类型的索引,如哈希和降序索引,可以显著提高查询性能。
110 0
|
存储 关系型数据库 MySQL
了解和认识索引
了解和认识索引 。
64 0
|
关系型数据库 MySQL 索引
索引(2)
索引(2)。
45 0
|
关系型数据库 MySQL 数据库
了解和认识索引
了解和认识索引。
56 0
|
存储 关系型数据库 MySQL
索引是什么
索引是什么
292 0
下一篇
DataWorks