ElasticSearch 索引 VS MySQL 索引(下)

本文涉及的产品
检索分析服务 Elasticsearch 版,2核4GB开发者规格 1个月
云数据库 RDS MySQL Serverless,0.5-2RCU 50GB
简介: ElasticSearch 索引 VS MySQL 索引

平衡二叉树的优化


但其实 MySQL 中的 Innodb 并没有采用跳表,而是使用的一个叫做 B+ 树的数据结构。


这个数据结构不像是二叉树那样大学老师当做基础数据结构经常讲到,由于这类数据结构都是在实际工程中根据需求场景在基础数据结构中演化而来。


比如这里的 B+ 树就可以认为是由平衡二叉树演化而来。


刚才我们提到二叉树的区间查询效率不高,针对这一点便可进行优化:


网络异常,图片无法展示
|


在原有二叉树的基础上优化后:所有的非叶子都不存放数据,只是作为叶子节点的索引,数据全部都存放在叶子节点。


这样所有叶子节点的数据都是有序存放的,便能很好的支持区间查询。


只需要先通过查询到起始节点的位置,然后在叶子节点中依次往后遍历即可。


当数据量巨大时,很明显索引文件是不能存放于内存中,虽然速度很快但消耗的资源也不小;所以 MySQL 会将索引文件直接存放于磁盘中。


这点和后文提到 elasticsearch 的索引略有不同。


由于索引存放于磁盘中,所以我们要尽可能的减少与磁盘的 IO(磁盘 IO 的效率与内存不在一个数量级)


通过上图可以看出,我们要查询一条数据至少得进行 4 次IO,很明显这个 IO 次数是与树的高度密切相关的,树的高度越低 IO 次数就会越少,同时性能也会越好。


那怎样才能降低树的高度呢?


网络异常,图片无法展示
|


我们可以尝试把二叉树变为三叉树,这样树的高度就会下降很多,这样查询数据时的 IO 次数自然也会降低,同时查询效率也会提高许多。


这其实就是 B+ 树的由来。


使用索引的一些建议


其实通过上图对 B+树的理解,也能优化日常工作的一些小细节;比如为什么需要最好是有序递增的?


假设我们写入的主键数据是无序的,那么有可能后写入数据的 id 小于之前写入的,这样在维护 B+树 索引时便有可能需要移动已经写好数据。


如果是按照递增写入数据时则不会有这个考虑,每次只需要依次写入即可。


所以我们才会要求数据库主键尽量是趋势递增的,不考虑分表的情况时最合理的就是自增主键。


整体来看思路和跳表类似,只是针对使用场景做了相关的调整(比如数据全部存储于叶子节点)。


ES 索引


MySQL 聊完了,现在来看看 Elasticsearch 是如何来使用索引的。


正排索引


在 ES 中采用的是一种名叫倒排索引的数据结构;在正式讲倒排索引之前先来聊聊和他相反的正排索引


网络异常,图片无法展示
|


以上图为例,我们可以通过 doc_id 查询到具体对象的方式称为使用正排索引,其实也能理解为一种散列表。


本质是通过 key 来查找 value。


比如通过 doc_id=4 便能很快查询到 name=jetty wang,age=20 这条数据。


倒排索引


那如果反过来我想查询 name 中包含了 li 的数据有哪些?这样如何高效查询呢?

仅仅通过上文提到的正排索引显然起不到什么作用,只能依次将所有数据遍历后判断名称中是否包含 li ;这样效率十分低下。


但如果我们重新构建一个索引结构:


网络异常,图片无法展示
|


当要查询 name 中包含 li 的数据时,只需要通过这个索引结构查询到 Posting List 中所包含的数据,再通过映射的方式查询到最终的数据。


这个索引结构其实就是倒排索引


Term Dictionary


但如何高效的在这个索引结构中查询到 li 呢,结合我们之前的经验,只要我们将 Term 有序排列,便可以使用二叉树搜索树的数据结构在o(logn) 下查询到数据。


将一个文本拆分成一个一个独立Term 的过程其实就是我们常说的分词。


而将所有 Term 合并在一起就是一个 Term Dictionary,也可以叫做单词词典。


  • 英文的分词相对简单,只需要通过空格、标点符号将文本分隔便能拆词,中文则相对复杂,但也有许多开源工具做支持(由于不是本文重点,对分词感兴趣的可以自行搜索)。


当我们的文本量巨大时,分词后的 Term 也会很多,这样一个倒排索引的数据结构如果存放于内存那肯定是不够存的,但如果像 MySQL 那样存放于磁盘,效率也没那么高。


Term Index


所以我们可以选择一个折中的方法,既然无法将整个 Term Dictionary 放入内存中,那我们可以为Term Dictionary 创建一个索引然后放入内存中。


这样便可以高效的查询Term Dictionary ,最后再通过Term Dictionary 查询到 Posting List


相对于 MySQL 中的 B+树来说也会减少了几次磁盘IO


网络异常,图片无法展示
|


这个 Term Index 我们可以使用这样的 Trie树 也就是我们常说的字典树 来存放。


更多关于字典树的内容请查看这里


网络异常,图片无法展示
|


如果我们是以 j 开头的 Term 进行搜索,首先第一步就是通过在内存中的 Term Index 查询出以 j 打头的 TermTerm Dictionary 字典文件中的哪个位置(这个位置可以是一个文件指针,可能是一个区间范围)。


紧接着在将这个位置区间中的所有 Term 取出,由于已经排好序,便可通过二分查找快速定位到具体位置;这样便可查询出 Posting List


最终通过 Posting List 中的位置信息便可在原始文件中将目标数据检索出来。


更多优化


当然 ElasticSearch 还做了许多针对性的优化,当我们对两个字段进行检索时,就可以利用 bitmap 进行优化。


比如现在需要查询 name=li and age=18 的数据,这时我们需要通过这两个字段将各自的结果 Posting List 取出。


网络异常,图片无法展示
|


最简单的方法是分别遍历两个集合,取出重复的数据,但这个明显效率低下。


这时我们便可使用 bitmap 的方式进行存储(还节省存储空间),同时利用先天的位与计算便可得出结果


[1, 3, 5]       ⇒ 10101

[1, 2, 4, 5]11011


这样两个二进制数组求与便可得出结果:


10001[1, 5]


最终反解出 Posting List[1, 5],这样的效率自然是要高上许多。


同样的查询需求在 MySQL 中并没有特殊优化,只是先将数据量小的数据筛选出来之后再筛选第二个字段,效率自然也就没有 ES 高。


当然在最新版的 ES 中也会对 Posting List 进行压缩,具体压缩规则可以查看官方文档,这里就不具体介绍了。


总结


最后我们来总结一下:


网络异常,图片无法展示
|


通过以上内容可以看出再复杂的产品最终都是基础数据结构组成,只是会对不同应用场景针对性的优化,所以打好数据结构与算法的基础后再看某个新的技术或中间件时才能快速上手,甚至自己就能知道优化方向。


更好的阅读体验请访问此处www.notion.so/ElasticSear…


相关实践学习
基于CentOS快速搭建LAMP环境
本教程介绍如何搭建LAMP环境,其中LAMP分别代表Linux、Apache、MySQL和PHP。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助     相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
2天前
|
安全 API 数据安全/隐私保护
Elasticsearch 通过索引阻塞实现数据保护深入解析
Elasticsearch 通过索引阻塞实现数据保护深入解析
|
2天前
|
存储 关系型数据库 MySQL
Mysql索引总结(1)
Mysql索引总结(1)
|
2天前
|
SQL 关系型数据库 MySQL
MySQL8.0索引新特性
MySQL8.0索引新特性
|
2天前
|
存储 SQL 关系型数据库
MySQL 索引
MySQL 索引
10 0
|
3天前
|
NoSQL 关系型数据库 MySQL
[AIGC] 对比MySQL全文索引,RedisSearch,和Elasticsearch的详细区别
[AIGC] 对比MySQL全文索引,RedisSearch,和Elasticsearch的详细区别
|
15天前
|
存储 关系型数据库 MySQL
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
【4月更文挑战第9天】InnoDB数据库使用B+树作为索引模型,其中主键索引的叶子节点存储完整行数据,非主键索引则存储主键值。主键查询只需搜索一棵树,而非主键查询需两次搜索,因此推荐使用主键查询以提高效率。在插入新值时,B+树需要维护有序性,可能导致数据页分裂影响性能。自增主键在插入时可避免数据挪动和页分裂,且占用存储空间小,通常更为理想。然而,如果场景仅需唯一索引,可直接设为主键以减少查询步骤。
16 1
【MySQL实战笔记】 04 | 深入浅出索引(上)-02
|
17天前
|
关系型数据库 MySQL 数据库
6. 了解过Mysql的索引嘛 ?
了解MySQL的索引类型,包括单列索引(普通、唯一、主键和全文索引)和组合索引。单列索引用于一列,如普通索引允许重复值,唯一索引和主键索引不允许,后者不允许空值。全文索引适用于特定文本字段。组合索引是多列的,遵循左前缀原则,通常推荐用于提高查询效率,除非是主键。
16 0
|
19天前
|
数据可视化 索引
elasticsearch head、kibana 安装和使用
elasticsearch head、kibana 安装和使用
|
1月前
|
存储 负载均衡 索引
linux7安装elasticsearch-7.4.0集群配置
linux7安装elasticsearch-7.4.0集群配置
113 0
|
2月前
|
存储 监控 搜索推荐
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)
在生产环境中部署Elasticsearch:最佳实践和故障排除技巧——安装篇(一)

推荐镜像

更多