インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

データベースでは、あまりにも多くのインデックス場合、アプリケーションのパフォーマンスは、インデックスが少なすぎる場合には、彼らが影響クエリのパフォーマンスを持っていますが、影響を受ける可能性があります。したがって、我々は、クエリのパフォーマンスを改善するための指標をもたらすために2、十分以上の間のバランスを追求しなければならないとインデックスは、データと他の操作を変更するには高すぎるので、過大な負荷につながりません。

記事は、側面を説明し、分類されたB +ツリーインデックス、インデックス、ハッシュインデックス、フルテキストインデックスからになります

B +ツリーインデックス

  • インデックス検索
  • インデックスを挿入します
  • インデックスの削除

カテゴリーインデックス

  • クラスタ化インデックス
  • セカンダリインデックス
  • 共同インデックス
  • インデックスをカバー

ハッシュインデックス

  • ハッシュアルゴリズム
  • アダプティブハッシュインデックス

フルテキストインデックス

  • 転置インデックス
  • 全文検索インデックスのキャッシュ
  • フルテキストインデックスのいくつかの制限

InnoDBは、我々が詳細に説明しようとしている、3つの共通の指標をサポートしてB +ツリーインデックス、ハッシュインデックス、フルテキストインデックスです。

B +ツリーインデックス

B +ツリーが進化最古から平衡二分木であるが、B +ツリーは二分木ではないので、図1に示すように、B +ツリーBは、二進(バイナリ)の代表ではなく、バランス(バランス)の代わりに。

2は、B +ツリーは、バランスディスクまたはダイレクトアクセスのために設計された他の補助装置、B +ツリーを見つけるために木である、すべてのノードが記録されているリーフノードは、リーフノードポインタによって、キーの順序に応じて同じ層に存在します接続されています。

、3、データベース機能でB +ツリーは、高ファンアウトであるため、ツリーのデータベースのB +高レコードキー、わずか2〜4倍IOの最大値を見つけるためにことを意味し、典型的には2~4層です第2の機械的ハードドライブ電流IO、IO 2〜4回当たり少なくとも100回の所要時間は、クエリのみ0.02 0.04秒であることを意味があります。

4、B +ツリーインデックスとキー、B +キー所与の特定の行にページを見つけることができないが行を見つけることができるだけツリーインデックスを見つけることで、データベース・ページメモリ読み出しは、メモリに再び見つけるために、最後に見つかりましたデータは、あなたが見つけたいです。

図5に示すように、データベースB +ツリーインデックスを分割することができ、クラスタ化インデックスと非クラスタ化インデックス、それがあるかどうか、その内部には、リーフ・ノードは、すべてのデータが格納されて、それが高度にバランスされ、B +ツリー実装クラスタ化インデックスまたは非クラスタ化インデックスであります異なるクラスタ化インデックスと非クラスタ化インデックスは、リーフノードの記憶情報の行全体であるかどうかです。各テーブルには、唯一のクラスタ化インデックスを持つことができます。

図6に示すように、各データ・ページ(リーフノード)のためのB +ツリーは、双方向リンクリストによって連結され、データ・ページ上の配列データはマスターキーに応じて順次格納されます。

2の高さB +ツリーを初めて目には、4ページは、記録されたファンアウト5を置くことができます。

図:B +ツリー高さ2

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

インデックス検索

また、バイナリ検索として知られているバイナリ検索を使用して、B +ツリーインデックスは、基本的な考え方はこれです:レコードの順序(昇順または降順)、プロセスを見つけるための方法を見つけるためにスーパージャンプを使用し、最初の中心点の列の数を命じましたあなたはその要素の中心点よりも小さい要素を探している場合は、位置の比較は、要素が左半分、それ以外の右半分を見つけるために削減されます、比較することによって、半分に減少した間隔を見て。

図中、参照48順序付けられたリストから、わずか3つのステップ。:

図:バイナリ検索

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

インデックスを挿入します

B +ツリーすばやくスピードを見つけることが、B +ツリーコストのバランスを維持することは非常に大きく、一般的に言って、木の挿入後バランスを確保するために1回以上利き手必要とします。

B +ツリーは、ツリーのバランスを維持するために挿入され、スプリットのページ(リーフノード)がかかり、メモリページは、基本的操作に分割されていることをディスクのディスクページを意味し、それは、分割されたページを最小限に抑える必要があり、自己IDの成長に、主キーとして、ページは解像度の大幅な削減、パフォーマンスの向上になります。

B +ツリーは3例を挿入しました

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

図:B +ツリー高さ2

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

私たちは例のB +ツリーによって挿入分析しました。

1は、我々は直接に、キー28を挿入して、現在のリーフページインデックスページがいっぱいでないことがわかりました。

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

2、我々は70このキーを挿入し、この時間は、元のリーフページが既に満杯であるが、索引ページは、まだ満杯ではない第2のケースで、表(3例B +ツリー挿入)に従い、その後、インサートリーフページ後の状況がある50,55,60,65,70私たちによると、60のリーフノード値の中央を分割します中間ノードのインデックスページに入れます

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

図3に示すように、画像の関係が示しているので、私は、各リーフノードに二重にリンクされたリスト・ポインタを追加することができなかった今回。最後に、我々は、レコード95、挿入表(B + 3例ツリー挿入)に沿って、第3ケース議論、つまりリーフページインデックスページをしていっぱいです、そして分割が二回行われる必要があります。

 

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

 

可以看到,不管怎么变化,B+树总是会保持平衡。但是为了保持平衡,对于新插入的键值可能需要做大量的拆分页(split)操作,而B+树主要用于磁盘,因此页的拆分意味着磁盘的操作,应该在可能的情况下尽量减少页的拆分。因此,B+树提供了旋转(rotation)的功能。

索引的删除

B+树使用填充因子(fill factor) 来控制树的删除变化,50%是填充因子可设的最小值,B+树的删除也同样必须保证删除后树的平衡性,删除的过程中会涉及合并叶子节或兄弟节点,但是都是为了保持树的平衡。

索引的分类

在了解B+树索引的本质和实现后,我们看看索引分为几类,聚集索引,辅助索引,联合索引,覆盖索引

聚集索引

就是按照每张表的主键构造一颗B+树,同时叶子节点存储整张表的行记录数,也将聚集索引的叶子节点成为“数据页”,聚集索引的特性决定了表中的行记录数据也是索引的一部分。同B+树数据结构一样,每个数据页都通过一个双向链表进行链接。

数据页只能按照一颗B+树进行排序,因此每张表只能有一个聚集索引,由于数据页定义了逻辑顺序,聚集索引能够很快的在数据页访问指针进行范围的查找数据。

聚集索引在物理上不是连续的,在逻辑上是连续的,前面已经说过是通过双向链表进行维护,物理存储可以不按照主键顺序存储。

辅助索引

辅助索引(也称非聚集索引),叶子节点并不包含行记录的全部数据。叶子节点除了包含键值外,每个叶子节点还包含了一个书签,该书签告诉InnoDB 存储引擎可以从哪里找到辅助索引相对应行的记录。因此InnoDB 存储引擎的辅助索引的书签就是相应整行数据的聚集索引键。

一个表中可以有多个辅助索引。例如,一个辅助索引树需要遍历3次才能找到主键索引,如果聚集索引树的高为同样为3,那么它还需要对聚集索引树进行三次查找,最终才能找到一个完整的数据页,因此一共需要6次IO访问才能得到最终的数据页。

联合索引

联合索引是指对表上多个列进行建立索引,联合索引本质还是一颗B+树,不同的是索引的键值数量不是1个,而是大于等于2。联合索引的键值在B+树中也是有序的,通过叶子节点可以在逻辑的顺序上读出所有数据。

覆盖索引

InnoDB存储引擎支持覆盖索引(或称索引覆盖),就是从辅助索引中就可以直接得到查询的记录,而不需要再次查询聚集索引中的记录。使用覆盖索引的好处就是,辅助索引不包括整行记录的所有信息,所以覆盖索引的大小要小于聚集索引,因此可以减少IO操作。

通俗的解释:

覆盖索引是非聚集组合索引的一种形式,它包括在查询里的Select、Join和Where子句用到的所有列(即建立索引的字段正好是覆盖查询语句[select子句]与查询条件[Where子句]中所涉及的字段,也就是索引包含了查询正在查找的所有数据

哈希索引

学习哈希索引之前,我们先了解一些基础的知识:哈希算法。哈希算法是一种常用的算法,时间复杂度为 O(1)。它不仅应用在索引上,各个数据库应用中也都会使用。

哈希算法

InnoDB存储引擎使用哈希算法来对字典进行查找,哈希碰撞采用转链表解决,哈希函数采用除法散列方式。

例如:当前参数InnoDBbufferpool_size大小为10M,则共有640个16k的页,对于缓冲页内存的哈希表来说,需要分配640×2=1280个槽,但是由于1280不是质数,所以需要取比1280更大的一点的质数,应该是1399,所以启动的时候,会分配1399个槽的哈希表,用来哈希查询所在的缓冲池中的页。

InnoDB存储引擎是通过除法散列到1399个其中的一个槽中。

自适应哈希索引

自适应哈希索引采用之前说的哈希表方式,不同的是哈希索引对字典类型的等值查找非常快,对范围查询就无能为力了。

所以说哈希索引只能用于搜索等值查询,范围查询是不能使用哈希索引。

全文索引

之前已经说过,B+树索引的特点,对于使用如下sql,是支持B+树索引的,只要content 加了B+树索引,就能利用索引进项快速查询。

我们通过 B+ 树索引可以进行前缀查找,如:

select * from blog where content like 
'xxx%'
;

只要为content列添加了B+树索引(聚集索引或辅助索引),就可快速查询。但在更多情况下,我们在博客或搜索引擎中需要查询的是某个单词,而不是某个单词开头,如:

select * from blog where content like 
'%xxx%'
;

此时如果使用B+树索引依然是全表扫描,而全文检索(Full-Text Search)就是将整本书或文章内任意内容检索出来的技术。

根据B+树索引的特点是不支持的,InnoDB存储引擎从1.2.x开始支持全文索引技术,其特性支MyISAM的全部功能。

具体实现原理接下来会介绍

倒排索引

全文检索使用倒排索引来实现,倒排索引同B+树索引一样,也是一种数据结构,它在辅助表中存储了单词与单词自身在一个或多个文档中所在位置的映射,这通常利用关联数组实现。

倒排索引它需要将分词(word)存储在一个辅助表(Auxiliary Table)中,为了提高全文检索的并行性能,共有6张辅助表。辅助表中存储了单词和单词在各行记录中位置的映射关系。它分为两种:倒排文件索引,详细倒排索引

1、inverted file index(倒排文件索引),表现为{单词,单词所在文档ID}

2、full inverted index(详细倒排索引),表现为{单词,(单词所在文档ID, 文档中的位置)}

全文检索表

DocumentIDText1Souyunku Technical team 2Go Technical stack

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

inverted file index(倒排文件索引)-辅助表存储为

倒排文件索引类型的辅助表存储为:

Documents 表现为{单词,单词所在文档ID}

NumberText 分词Documents 1Souyunku12Technical1,23team14Go25stack2

インタビュアー:あなたはMySQLのインデックスの原則の実現について話?

 

full inverted index( 详细倒排索引)-辅助表存储为

详细倒排索引类型的辅助表存储为,占用更多空间,也更好的定位数据,比提供更多的搜索特性:

Documents 表现为{单词,(单词所在文档ID, 文档中的位置)}

NumberTextDocuments

1Souyunku1:12Technical1:2 ,2:23team1:34Go2:15stack2:3

全文检索索引缓存

辅助表是存在与磁盘上的持久化的表,由于磁盘I/O比较慢,因此提供FTS Index Cache(全文检索索引缓存)来提高性能。FTS Index Cache是一个红黑树结构,根据(word, list)排序,在有数据插入时,索引先更新到缓存中,而后InnoDB存储引擎会批量进行更新到辅助表中。

当数据库宕机时,尚未落盘的索引缓存数据会自动读取并存储,配置参数innodbftcache_size控制缓存的大小,默认为32M,提高该值,可以提高全文检索的性能,但在故障时,需要更久的时间恢复。

あなたはデータを削除すると、一定期間後に、インデックスが非常に大きくなるので、InnoDBのインデックスデータは、削除されたが、削除補助テーブルに格納されていない、手動でインデックスの最適化テーブルによって記録された無効なコマンドを削除することができます。あなたは非常に多くのコンテンツを削除する必要がある場合は、アプリケーションの可用性に影響を与えるだろう、削除されたすべての単語を制御するinnodbftnumwordoptimizeパラメータの数、デフォルトは2000で、削除された大きさを制御するパラメータを調整することができますユーザー。

フルテキストインデックスのいくつかの制限

1、今だけのMyISAMとInnoDBのをサポート

2、パーティションテーブルをサポートしていません。

図3に示すように、複数列のテキスト検索インデックスは、文字セットと文字列の同じ組み合わせを使用する必要があります

4、象形文字をサポートしていません。NGRAM単語に必要

5、各フィールドのフルテキストインデックスを統一する必要があります

6、ルックアップ列での試合は()フルテキストインデックスでは年間で定義する必要があります

()に対して、図7は、文字列定数である、としなければなりません

8、インデックスヒントはさらに悪くなります

9、InnoDB内で、フルテキストインデックス付きの列に関連するすべてのDML操作トランザクションがコミットされた場合にのみ、(更新、挿入、削除)、実行。中間ワード、マーカーなどであってもよいです

10は、ワイルドカード%を使用することはできません

11、言語はなど、中国語、日本語、韓国語、など何の単語の区切り文字(区切り文字)を、持っていないサポートしていません。

おすすめ

転載: blog.csdn.net/mifffy_java/article/details/90768257
おすすめ