MySQL 인덱스 VS ElasticSearch 인덱스

coldplay.xixi
풀어 주다: 2020-10-09 17:03:57
앞으로
1797명이 탐색했습니다.

오늘의 MySQL 데이터베이스 칼럼에서는 MySQL 인덱스와 ElasticSearch 인덱스의 비교를 소개합니다.

MySQL 인덱스 VS ElasticSearch 인덱스

서문

그동안 제품의 검색 기능을 유지해왔는데 관리 콘솔에 elasticsearch가 보일 때마다 어떻게 달성하는지 궁금하네요. 이러한 효율적인 쿼리 효율성. elasticsearch 这么高效的查询效率我都很好奇他是如何做到的。

MySQL 인덱스 VS ElasticSearch 인덱스

这甚至比在我本地使用 MySQL 通过主键的查询速度还快。

MySQL 인덱스 VS ElasticSearch 인덱스

为此我搜索了相关资料:

MySQL 인덱스 VS ElasticSearch 인덱스

这类问题网上很多答案,大概意思呢如下:

  • ES 是基于 Lucene 的全文检索引擎,它会对数据进行分词后保存索引,擅长管理大量的索引数据,相对于 MySQL 来说不擅长经常更新数据及关联查询。

说的不是很透彻,没有解析相关的原理;不过既然反复提到了索引,那我们就从索引的角度来对比下两者的差异。

MySQL 索引

先从 MySQL 说起,索引这个词想必大家也是烂熟于心,通常存在于一些查询的场景,是典型的空间换时间的案例。

以下内容以 Innodb 引擎为例。复制代码
로그인 후 복사

常见的数据结构

假设由我们自己来设计 MySQL 的索引,大概会有哪些选择呢?

散列表

首先我们应当想到的是散列表,这是一个非常常见且高效的查询、写入的数据结构,对应到 Java 中就是 HashMap

MySQL 인덱스 VS ElasticSearch 인덱스

这个数据结构应该不需要过多介绍了,它的写入效率很高O(1),比如我们要查询 id=3 的数据时,需要将 3 进行哈希运算,然后再这个数组中找到对应的位置即可。

但如果我们想查询 1≤id≤6 这样的区间数据时,散列表就不能很好的满足了,由于它是无序的,所以得将所有数据遍历一遍才能知道哪些数据属于这个区间。

有序数组

MySQL 인덱스 VS ElasticSearch 인덱스

有序数组的查询效率也很高,当我们要查询 id=4 的数据时,只需要通过二分查找也能高效定位到数据O(logn)

同时由于数据也是有序的,所以自然也能支持区间查询;这么看来有序数组适合用做索引咯?

自然是不行,它有另一个重大问题;假设我们插入了 id=2.5 的数据,就得同时将后续的所有数据都移动一位,这个写入效率就会变得非常低。

平衡二叉树

既然有序数组的写入效率不高,那我们就来看看写入效率高的,很容易就能想到二叉树;这里我们以平衡二叉树为例:

MySQL 인덱스 VS ElasticSearch 인덱스

由于平衡二叉树的特性:

左节点小于父节点、右节点大于父节点。

所以假设我们要查询 id=11 的数据,只需要查询 10—>12—>11 便能最终找到数据,时间复杂度为O(logn),同理写入数据时也为O(logn)

但依然不能很好的支持区间范围查找,假设我们要查询5≤id≤20 的数据时,需要先查询10节点的左子树再查询10节点的右子树最终才能查询到所有数据。

导致这样的查询效率并不高。

跳表

跳表可能不像上边提到的散列表、有序数组、二叉树那样日常见的比较多,但其实 Redis 中的 sort set

MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜이것은 내 로컬 컴퓨터에서 MySQL을 사용하여 기본 키로 쿼리하는 것보다 훨씬 빠릅니다. 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜관련 정보를 검색해봤습니다: 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜이런 종류의 질문에 대한 답변은 인터넷에 많이 있습니다. 일반적인 의미는 다음과 같습니다. 🎜
  • ES Lucene은 데이터를 분할하여 인덱스를 저장하는 전체 텍스트 검색 엔진입니다. MySQL에 비해 대용량 인덱스 데이터를 관리하는 데 적합합니다. 데이터 및 관련 쿼리를 자주 업데이트하는 데 능숙하지 않습니다.
🎜설명이 아주 꼼꼼하지도 않고 관련 원리를 분석하지도 않았는데, 지수가 반복해서 언급되기 때문에 둘의 차이점을 지수 관점에서 비교해보겠습니다. 🎜

MySQL index🎜🎜 먼저 MySQL부터 시작해 보겠습니다. 누구나 index라는 단어에 익숙할 것입니다. 일반적으로 일부 쿼리 시나리오에 존재하며 일반적인 A입니다. 시간과 공간을 교환하는 경우. 🎜rrreee

공통 데이터 구조

🎜우리가 MySQL의 인덱스를 직접 디자인한다고 가정해 보겠습니다. 옵션은 무엇입니까? 🎜

해시 테이블

🎜우리가 가장 먼저 생각해야 할 것은 해시 테이블입니다. 이는 쿼리 및 쓰기에 매우 일반적이고 효율적인 데이터 구조이며 JavaHashMap🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜이 데이터 구조는 많은 소개가 필요하지 않으며 쓰기 효율성이 매우 높습니다 O(1) code>, 예를 들어 <code>id=3의 데이터를 쿼리하려면 3을 해시한 다음 이 배열에서 해당 위치를 찾아야 합니다. 🎜🎜하지만 1≤id≤6과 같은 간격 데이터를 쿼리하려면 해시 테이블이 순서가 지정되어 있지 않기 때문에 어떤 데이터에 속하는지 알아야 합니다. 이 간격. 🎜

정렬된 배열

🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜순서 배열의 쿼리 효율성도 매우 높습니다. id=4를 쿼리하려는 경우 code > 데이터인 경우 이진 검색을 통해서만 <code>O(logn) 데이터를 효율적으로 찾을 수 있습니다. 🎜🎜동시에 데이터도 정렬되어 있기 때문에 자연스럽게 간격 쿼리를 지원할 수 있습니다. 그러면 정렬된 배열이 인덱스로 사용하기에 적합한 것 같은데요? 🎜🎜물론, id=2.5인 데이터의 경우 이후의 모든 데이터를 동시에 1비트씩 이동해야 하므로 쓰기 효율성이 매우 낮아집니다. 🎜

균형 이진 트리

🎜순서 배열의 쓰기 효율성은 높지 않으므로 쓰기 효율성이 높은 것들을 살펴보겠습니다. 이진 트리; 여기서는 균형 잡힌 이진 트리를 예로 들어 보겠습니다. 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜균형 이진 트리의 특성으로 인해: 🎜
🎜왼쪽 노드는 부모 노드보다 작고 오른쪽 노드는 상위 노드보다 큽니다. 🎜
🎜그래서 id=11의 데이터를 쿼리한다고 가정하면 10—>12—>11만 쿼리하면 최종적으로 찾을 수 있습니다. 데이터, 시간 복잡도는 O(logn)이고 마찬가지로 데이터를 쓸 때도 O(logn)입니다. 🎜🎜하지만 여전히 간격 검색을 잘 지원하지 않습니다. 5≤id≤20의 데이터를 쿼리한다고 가정하면 먼저 10개 노드의 왼쪽 하위 트리를 쿼리한 다음 오른쪽을 쿼리해야 합니다. 10개 노드의 하위 트리에서만 모든 데이터를 쿼리할 수 있습니다. 🎜🎜결과적으로 이러한 쿼리 효율성은 높지 않습니다. 🎜

스킵 테이블

🎜스킵 테이블은 위에서 언급한 해시 테이블, 순서 배열, 이진 트리만큼 일반적이지 않을 수 있지만 실제로 Redis는 의 code>sort set는 건너뛰기 목록을 사용하여 구현됩니다. 🎜

점프 테이블로 구현한 데이터 구조의 장점을 간략하게 소개합니다.

우리 모두는 순서가 지정된 연결 목록을 쿼리하는 것조차 효율적이지 않다는 것을 알고 있습니다. 이진 검색에 배열 첨자를 사용할 수 없기 때문에 시간 복잡도는 o(n)o(n)

但我们也可以巧妙的优化链表来变相的实现二分查找,如下图:

MySQL 인덱스 VS ElasticSearch 인덱스

我们可以为最底层的数据提取出一级索引、二级索引,根据数据量的不同,我们可以提取出 N 级索引。

当我们查询时便可以利用这里的索引变相的实现了二分查找。

假设现在要查询 id=13 的数据,只需要遍历 1—>7—>10—>13 四个节点便可以查询到数据,当数越多时,效率提升会更明显。

同时区间查询也是支持,和刚才的查询单个节点类似,只需要查询到起始节点,然后依次往后遍历(链表有序)到目标节点便能将整个范围的数据查询出来。

同时由于我们在索引上不会存储真正的数据,只是存放一个指针,相对于最底层存放数据的链表来说占用的空间便可以忽略不计了。

平衡二叉树的优化

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

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

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

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

MySQL 인덱스 VS ElasticSearch 인덱스

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

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

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

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

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

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

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

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

MySQL 인덱스 VS ElasticSearch 인덱스

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

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

使用索引的一些建议

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

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

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

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

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

ES 索引

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

正排索引

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

하지만 영리하게도 가능합니다. 아래와 같이 변장에서 이진 검색을 구현하도록 연결 목록을 최적화합니다. 🎜
MySQL 인덱스 VS ElasticSearch 인덱스
🎜가장 낮은 1단계 색인과 2단계 색인을 추출할 수 있습니다. 레벨 데이터 레벨 인덱스는 데이터의 양에 따라 N레벨 인덱스를 추출할 수 있습니다. 🎜🎜쿼리할 때 여기 색인을 사용하여 변장한 이진 검색을 구현할 수 있습니다. 🎜🎜이제 id=13의 데이터를 쿼리하려고 한다고 가정하고 1—>7—>10—>13의 4개 노드만 순회하면 됩니다. > 데이터를 쿼리하려면 숫자가 클수록 효율성 향상이 더욱 분명해집니다. 🎜🎜동시에 간격 쿼리도 지원됩니다. 지금의 단일 노드를 쿼리하는 것과 유사하게 시작 노드만 쿼리한 다음 대상 노드까지 역순회(🎜연결된 목록 순서🎜)하면 됩니다. 전체 데이터 범위를 쿼리합니다. 🎜🎜동시에 실제 데이터를 인덱스에 저장하지 않고 포인터만 저장하기 때문에 데이터가 저장되는 하단의 연결 리스트에 비하면 차지하는 공간은 미미합니다. 🎜

균형 이진 트리 최적화

🎜그러나 실제로 MySQLInnodb는 스킵 테이블을 사용하지 않습니다. 그러나 B+ 트리라는 데이터 구조가 사용됩니다. 🎜🎜이 데이터 구조는 대학 교사들이 기본 데이터 구조로 자주 이야기하는 이진 트리와는 다릅니다. 이러한 유형의 데이터 구조는 실제 프로젝트의 수요 시나리오 기반 기본 데이터 구조에서 진화되기 때문입니다. 🎜🎜예를 들어 여기의 B+ 트리는 균형 이진 트리에서 진화된 것으로 간주할 수 있습니다. 🎜🎜방금 우리는 이진 트리의 간격 쿼리 효율성이 높지 않다고 언급했습니다. 이는 최적화될 수 있습니다: 🎜
MySQL 인덱스 VS ElasticSearch 인덱스
🎜원래 이진 트리를 기반으로 최적화한 후: 리프가 아닌 항목은 데이터를 저장하지 않으며 리프 노드에 대한 인덱스 역할만 하며 모든 데이터는 리프 노드에 저장됩니다. 🎜🎜이렇게 하면 모든 리프 노드의 데이터가 순서대로 저장되며 간격 쿼리를 잘 지원할 수 있습니다. 🎜🎜먼저 시작 노드의 위치를 ​​쿼리한 다음 리프 노드에서 뒤로 탐색하면 됩니다. 🎜🎜데이터의 양이 많으면 인덱스 파일이 메모리에 저장되지 않는 것은 당연합니다. 속도는 빠르지만 리소스를 많이 소모하므로 MySQL이 인덱스 파일을 저장합니다. 디스크에 직접. 🎜🎜뒤에 언급되는 Elasticsearch 지수와는 조금 다릅니다. 🎜🎜인덱스는 디스크에 저장되기 때문에 디스크에 대한 IO를 최대한 줄여야 합니다. (디스크 IO의 효율성은 메모리의 효율성과 같은 크기가 아닙니다.) 🎜🎜에서 볼 수 있듯이 위 그림에서 데이터 조각을 IO의 4배 이상 쿼리해야 합니다. IO 수가 트리 높이와 밀접하게 관련되어 있다는 것은 명백합니다. 트리 높이가 낮을수록 IO 수가 줄어듭니다. 그리고 성능이 더 좋아집니다. 🎜🎜그렇다면 어떻게 나무의 높이를 줄일 수 있을까요? 🎜MySQL 인덱스 VS ElasticSearch 인덱스
🎜이진 트리를 삼항 트리로 변경하면 트리 높이가 많이 줄어들고 IO 개수도 줄어듭니다. 쿼리하는 데이터가 자연스럽게 줄어들 것입니다. 동시에 쿼리 효율성도 많이 향상됩니다. 🎜
🎜이것이 사실 B+트리의 유래입니다. 🎜

인덱스 사용에 대한 몇 가지 제안

🎜실제로 위 그림의 B+ 트리를 이해하면 다음과 같은 결과를 얻을 수 있습니다. 또한 일상 업무를 최적화하는 것이 순차적으로 증가하는 것이 가장 좋은 이유와 같은 몇 가지 작은 세부 사항입니다. 🎜🎜우리가 작성하는 기본 키 데이터가 순서가 없다고 가정하면 나중에 작성되는 데이터의 ID가 이전에 작성된 데이터의 ID보다 작을 수 있습니다. 이런 식으로 유지 관리 시 이미 작성된 데이터를 이동해야 할 수도 있습니다. B+트리 인덱스가 좋습니다. 🎜🎜데이터를 증분식으로 쓰는 경우에는 이런 고려 사항이 없습니다. 매번 순차적으로만 쓰면 됩니다. 🎜
🎜그래서 데이터베이스의 기본 키는 최대한 증가하는 추세를 갖도록 요구합니다. 가장 합리적인 것은 분할 테이블의 상황을 고려하지 않고 기본 키를 자동 증가시키는 것입니다. 🎜
🎜전체적으로 아이디어는 사용 시나리오에 대해 관련 조정이 이루어졌다는 점을 제외하면 스킵 테이블과 유사합니다(예: 모든 데이터가 리프 노드에 저장됨). 🎜

ES Index

🎜MySQL 채팅을 마친 후 Elasticsearch가 인덱스를 어떻게 사용하는지 살펴보겠습니다. 🎜

정방향 인덱스

🎜ES에서는 역 인덱스라는 데이터 구조를 정식으로 사용하는데, 인덱싱에 앞서, 반대 정방향 인덱스. 🎜
MySQL 인덱스 VS ElasticSearch 인덱스

위 그림을 예로 들면, doc_id를 통해 특정 객체를 조회할 수 있는 방식을 forward index를 사용한다고 할 수도 있습니다. 일종의 분산된 목록으로 이해됩니다. doc_id 查询到具体对象的方式称为使用正排索引,其实也能理解为一种散列表。

本质是通过 key 来查找 value。

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

倒排索引

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

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

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

MySQL 인덱스 VS ElasticSearch 인덱스

当要查询 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

MySQL 인덱스 VS ElasticSearch 인덱스

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

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

MySQL 인덱스 VS ElasticSearch 인덱스

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

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

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

更多优化

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

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

핵심은 열쇠를 통해 가치를 찾는 것입니다.
MySQL 인덱스 VS ElasticSearch 인덱스예를 들어 doc_id=4를 통해 name=jetty wang,age=20 데이터를 빠르게 쿼리할 수 있습니다.

역 인덱스

nameli가 포함된 데이터를 쿼리하고 싶다면 다음이 있습니다. 것들? 이런 식으로 효율적으로 쿼리하는 방법은 무엇입니까?

위에서 언급한 정방향 인덱스만 사용하는 것은 효과가 없습니다. 모든 데이터를 순서대로 탐색한 다음 이름에 li가 포함되어 있는지 확인하는 것은 매우 비효율적입니다.

🎜그러나 인덱스 구조를 재구축한다면: 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜 nameli가 포함된 데이터를 쿼리하려면 다음만 사용하면 됩니다. 인덱스 구조 게시 목록에 포함된 데이터를 조회한 후, 매핑을 통해 최종 데이터를 조회합니다. 🎜🎜이 인덱스 구조는 실제로 역 인덱스입니다. 🎜

용어 사전

🎜하지만 하는 한 이전 경험을 결합하여 이 인덱스 구조에서 <code>li를 효율적으로 쿼리하는 방법은 무엇입니까? Term은 순서대로 배열되어 있으며, 이진트리 탐색트리의 데이터 구조를 이용하여 o(logn) 아래의 데이터를 조회할 수 있다. 🎜🎜텍스트를 독립적인 용어로 분할하는 과정을 실제로 우리는 단어 분할이라고 부릅니다. 🎜🎜그리고 모든 용어를 합치면 단어 사전이라고도 할 수 있는 용어 사전이 됩니다. 🎜
  • 영어 단어 분할은 공백과 구두점으로만 구분하면 됩니다. 중국어는 비교적 복잡하지만 이를 지원하는 오픈 소스 도구도 많이 있습니다. 이 글의 초점은 아니고, 단어분할에 관심이 있어서 직접 검색하셔도 됩니다.)
🎜텍스트 볼륨이 크면 단어 분할 후 용어가 많아질 것입니다. 이러한 반전된 인덱스 데이터 구조가 메모리에 저장되면 절대 그렇지 않습니다. 충분하지만 MySQL과 같은 디스크에 저장하면 효율성이 그다지 높지 않습니다. 🎜

용어 색인

🎜그래서 절충 방법을 선택할 수 있습니다. 용어 사전 전체를 메모리에 넣을 수 없으므로 색인을 사용합니다. 용어 사전용으로 생성되어 메모리에 배치될 수 있습니다. 🎜🎜이렇게 하면 용어사전을 효율적으로 조회할 수 있고, 마지막으로 용어사전을 통해 게시목록을 조회할 수 있습니다. 🎜🎜MySQLB+ 트리와 비교하면 디스크 IO도 몇 배로 줄어듭니다. 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜이 용어 색인을 사용하여 사전 트리라고 부르는 Trie 트리를 사용하여 저장할 수 있습니다. 코드>. 🎜🎜사전나무에 대한 자세한 내용은 여기를 참조하세요. 🎜🎜MySQL 인덱스 VS ElasticSearch 인덱스🎜🎜🎜🎜 j로 시작하는 Term을 검색하는 경우 첫 번째 단계는 메모리 코드에서 Term Index 쿼리를 사용하는 것입니다. 용어 사전 사전 파일에서 j로 시작하는 용어의 위치(이 위치는 간격 범위일 수 있는 파일 포인터일 수 있음) . 🎜🎜그런 다음 이 위치 범위의 용어를 모두 꺼내면 이진 검색을 통해 특정 위치를 빠르게 찾을 수 있으며 게시 목록을 쿼리할 수 있습니다. . 🎜🎜마지막으로 <code>게시 목록의 위치 정보를 통해 원본 파일에서 대상 데이터를 검색할 수 있습니다. 🎜

추가 최적화

🎜물론 ElasticSearch도 두 개의 필드를 검색할 때 많은 대상 최적화를 수행했습니다. 비트맵을 사용할 수 있습니다. 최적화를 위해. 🎜🎜예를 들어, 이제 name=li 및 age=18의 데이터를 쿼리해야 합니다. 이때 이 두 필드를 사용하여 해당 결과 Posting List. 🎜🎜🎜🎜🎜🎜🎜가장 간단한 방법은 두 컬렉션을 별도로 탐색하여 중복 데이터를 제거하는 것이지만 이는 확실히 비효율적입니다. 🎜<p>이때 <code>bitmap 방법을 사용하여 저장(저장 공간도 절약)할 수 있으며 동시에 고유한 비트와 ** 계산을 사용하여 결과를 받아보세요 . **bitmap 的方式进行存储(还节省存储空间),同时利用先天的位与 **计算便可得出结果。**

[1, 3, 5]       ⇒ 10101

[1, 2, 4, 5]11011

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

10001[1, 5]

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

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

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

总结

最后我们来总结一下:

MySQL 인덱스 VS ElasticSearch 인덱스

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

最后画个饼,后续我会尝试按照 ES

[1, 3, 5] ⇒ 10101

[1, 2, 4, 5]11011 결과는 두 개의 이진 배열을 합산하여 얻을 수 있습니다:

10001[1, 5]🎜🎜마지막으로 해결책은 게시 목록[1, 5]이므로 당연히 효율성이 훨씬 높아집니다. 🎜🎜 MySQL에는 동일한 쿼리 요구 사항에 대한 특별한 최적화가 없습니다. 단지 작은 데이터를 먼저 필터링한 다음 두 번째 필드를 필터링하는 것은 당연히 ES만큼 좋지 않습니다. 코드> 높음. 🎜🎜물론, ES 최신 버전에서는 게시 목록도 압축됩니다. 자세한 내용은 소개하지 않겠지만 구체적인 압축 규칙은 공식 문서에서 확인하실 수 있습니다. 여기. 🎜

요약

🎜마지막으로 요약해 보겠습니다. 🎜MySQL 인덱스 VS ElasticSearch 인덱스
🎜위 내용에서 알 수 있듯이 복잡한 제품은 궁극적으로 다양한 애플리케이션 시나리오에만 최적화된 기본 데이터 구조로 구성됩니다. 따라서 데이터 구조와 알고리즘에 대한 탄탄한 기초를 갖춘 후에만 새로운 기술이나 미들웨어를 빠르게 시작하거나 직접 배울 수도 있습니다. .최적화 방향을 알 수 있습니다. 🎜🎜마지막으로 파이를 그려보겠습니다. 앞으로는 ​​ES 역인덱스 아이디어를 바탕으로 직접 작성하는 것만으로도 독립형 검색 엔진을 만들 수 있도록 노력하겠습니다. 나의 이해를 깊게 해주세요. 🎜🎜🎜관련 무료 학습 권장 사항: 🎜mysql 데이터베이스🎜(동영상)🎜🎜

위 내용은 MySQL 인덱스 VS ElasticSearch 인덱스의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:juejin.im
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
최신 이슈
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿
회사 소개 부인 성명 Sitemap
PHP 중국어 웹사이트:공공복지 온라인 PHP 교육,PHP 학습자의 빠른 성장을 도와주세요!