目次
6.4InnoDBの基盤となるストレージエンジンインデックスの実装
7.8 InnoDBが主キーを作成する必要があるのはなぜですか?
7.10自動インクリメントの主キーを使用することが推奨されるのはなぜですか?
7.11InnoDBの非主キーインデックスが主キー値を格納する理由
7.12B-Treeの代わりにB + Treeを使用する理由
1はじめに
著者は当初、データベースの知識ポイントはインタビューの前に覚えておくとよいと考えていましたが、実際には、これはまったく実現可能ではありません。1つは忘れがちで、もう1つはまったく柔軟性がなく、インタビュアーは質問を変えることに唖然とします。この記事の長さの大部分は、インデックスの基本的な実装に関するものです。インタビューの質問は最後に配置されています。以前の低レベルの実装を読むことができれば、インタビューの質問はまったく問題ありません。もちろん、面接の質問を直接見たい人は、目次に直接移動できます。7つのポイント:面接の質問の分析にインデックスを付け、最後に自分で作成したインデックスブレインマップを添付します。
2.インデックスデータ構造の分類
インデックスの基礎となるデータ構造は、データを参照した後、多くのカテゴリに分類されます。ツリーのような構造には、バイナリ検索ツリー(Binary Search Tree)、セルフバランシングバイナリサーチツリー(Self-balancing Binary Search Tree)の5種類があります。 )。)、B-Tree、Trie-Tree、Spatial DataPartitioningTree。詳細を下図に示します。
カテゴリー | 木の名前 |
---|---|
二分探索木(二分探索木) | 二分探索木、デカルト木、T木 |
自己平衡二分探索木(自己平衡二分探索木) | AA木、AVL木、赤黒木、スプレー木 |
Bツリー | 2-3ツリー、2-3-4ツリー、Bツリー、B +ツリー、B *ツリー |
トライ(トライツリー) | 接尾辞木、基数木、三叉神経探索木、高速接頭辞木 |
空間データ分割ツリー(空間データ分割ツリー) | Rツリー、R +ツリー、R *ツリー、ラインセグメントツリー、優先度Rツリー |
この記事では、主に、初期バージョンで使用されていたバイナリツリーとBツリー、インタビューで常に尋ねられる赤黒木、現在のバージョンで使用されているB +ツリーなど、MySQLインデックスの知識を分析します。。
3.二分探索木
二分探索木: n個の有限要素のコレクションです。コレクションは空であるか、ルートと呼ばれる要素と、左側のサブツリーと右側のサブツリーと呼ばれる2つのばらばらの二分木で構成されます。構成は、優れた検索パフォーマンスを備えた二分探索木です。 、これは二分探索に相当します。MySQLが二分木を使用しない理由について、次の図を見てみましょう。1から7までの7つのデータがあります。挿入順序が4、3、5、2、6、1、7の場合、結果は次のようになります。一種の高さ4の木。データ構造の可視化のウェブサイトのアドレス、自分自身でそれを試してみたいお友達はをクリックして試すことができます。
ただし、データ挿入シーケンスが1、2、3、4、5、6、および7になると、結果は7ノードのリンクリストになります。
二分木の問題点:二分木の深さは要素の挿入順序に依存し、挿入されたデータが比較的大きい場合、木の深さは比較的高くなります。データクエリの時間は、主にディスクIOの数に依存します。バイナリツリーの深さが深いほど、検索の数が多くなり、パフォーマンスが低下します。最悪の場合、リンクリストに縮退します。
4.赤黒木(自己平衡二分探索木)
赤黒木:赤黒木は特殊なAVL木(平衡二分木)であり、挿入と削除の際の特定の操作を通じて二分探索木のバランスを維持し、より高い検索パフォーマンスを実現します。複雑ですが、最悪の場合の実行時間も非常に長く、実際には効率的です。検索、挿入、削除をO(log n)時間で実行できます。ここで、nはツリー内にあります。要素の数。特徴:左右のサブツリー間の高さの差の絶対値は1を超えず、左右のサブツリーは両方とも平衡二分木です。赤黒木は、1、2、3、4、5、6、7、および7つの要素のGIF図を挿入します。
要素7のプロセスを見つける:
赤黒木に関する問題:ツリーの片側が長くなりすぎてリンクリストに縮退しないようにしてください。これにより、高さが効果的に減少し、高さが小さいほどI / Oルックアップの数が減少します。パフォーマンスはバイナリツリーよりも優れています。ただし、赤黒木のノードは2つの子ノードしか持つことができません。リンクリストの劣化の問題はバランスが取れていますが、全体の高さは依然として高すぎます。
5.Bツリー
Bツリー:Bツリーは単なるマルチフォークツリーです。各リーフには、データと次のノードへのポインタが格納されます。Bツリーは1、2、3、4、5、6、7、7要素のGIF画像を挿入します。
要素7のプロセスを見つける:
Bツリーの特徴
1)葉の節は同じ深さを持っています
2)すべてのインデックス要素が繰り返されるわけではありません
3)ノードのデータインデックスは左から右に増加します
クエリプロセスから、B-Treeのクエリ効率は平衡二分木よりも高くはないように見えますが、クエリによって渡されるノードの数は、バイナリツリーのノード数より1つ少ないことがわかります。データ量が多い場合の回数が大幅に少なくなることを意味します。ディスクIOにより、パフォーマンスが大幅に向上します。前のBツリー操作の図では、要素が1、2、3のような値であることがわかりますが、データベース内のデータはデータの一部です。データベースがBツリーにデータを格納している場合データ構造、データはどのように保存されますか?
具体的なストレージは次のとおりです。
データベースストレージでは、要素部分をkey-dataの形式に分割します。ここで、keyはデータの主キーであり、dataは特定のデータです。
Bツリーの問題:Bツリーは各ノードにインデックスとデータを格納するため、検索時にインデックスとデータをメモリにロードする必要があります。これはあまり費用対効果が高くありません。メモリリソースは非常に貴重であり、だからもっと保存するインデックスは良くないだろうか。
6.B +ツリー
6.1 B + Treeの概要と特徴
B + Tree: B-Treeに基づく最適化であり、外部ストレージのインデックス構造の実装により適しています。
B + Treeの機能:
1)非リーフノードはデータを保存せず、インデックス(冗長性)のみを保存します。これにより、より多くのインデックスを確実に保存できます。
2)リーフノードはすべてのインデックスフィールドを格納します
3)リーフノードは、インターバルアクセスのパフォーマンスを向上させるためにポインタで接続されています
6.2 B + Treeストレージデータの例
B + Treeストレージデータのサンプル図:
6.3MyISAMストレージエンジンインデックスの実装
select * from tablename where id = 20 MyISAMクエリプロセス:最初にMYIファイルに移動してインデックスデータをクエリし、id = 20のリーフノードを見つけて、20に対応するデータファイルアドレス「0x6A」を取得し、 MYDファイル、このファイルアドレスに従って、特定のID = 20の行レコードを見つけます。
6.4InnoDBの基盤となるストレージエンジンインデックスの実装
注:InnoDBの主キーインデックスはクラスター化インデックス(インデックスとデータは一緒に格納されます)であり、セカンダリインデックスのインデックス位置に格納されているデータは主キーIDの値です。
select * from tablename where id = 20 InnoDB主キーインデックスクエリプロセス:IDBファイルから直接id = 20のインデックスをクエリして、現在の行データを直接取得します。
select * from tablename where name = 'Alice' InnoDB non-primary key index query process:IDBファイルからname = Aliceのインデックスを直接クエリし、プライマリキーID = 18を取得してから、ID18のデータを検索します。現在のファイル。
7.インデックス関連の面接質問分析
7.1インデックスとは
データベースは、データに加えて、特定の検索アルゴリズムを満たすデータ構造も維持します。これらのデータ構造は、特定の方法でデータを参照するため、これらのデータ構造で効率的な検索を実行できます。これらのデータ構造はインデックスです。
7.2インデックスの分類
単一値インデックス:インデックスには単一の列のみが含まれ、テーブルには複数の単一値インデックスが存在する可能性があります
一意のインデックス:インデックス列の値は一意である必要があり、空にすることができます
複合インデックス:インデックスには複数の列が含まれます
7.3インデックスの利点
1)データ検索効率を改善し、ディスクIOコストを削減します
2)データをソートすることにより、ソートのコストを削減します
7.4インデックス作成のデメリット
1)インデックスはクエリの効率を向上させますが、MySQLはデータを保存するだけでなく、データとインデックスの関係も維持するため、更新、変更、削除の効率も低下します。
2)インデックスを維持するためのコストが必要です。パフォーマンスの高いインデックスには、最適なソリューションを見つけるための絶え間ない試みが必要です。
7.5どのような状況でインデックス作成に適しているか
1)主キーは自動的に一意のインデックスを作成します
2)クエリ条件として頻繁に使用されるフィールド(whereの後のフィールド)
3)クエリ内の他のテーブルに関連付けられているフィールド(さまざまな結合後のフィールド)
4)単一値/複合インデックスの選択?(高い同時実行性は複合インデックスを選択する傾向があります)
5)クエリ内の並べ替えられたフィールド
6)クエリの統計またはグループ化フィールド
7.6どのような状況でインデックス作成に適していないか
1)テーブルデータが少なすぎる
2)頻繁に更新されるフィールド
3)その後使用されないフィールド
7.7インデックス障害はいつ発生しますか?
1)ワイルドカード( '%abc')で始まるように、インデックスが無効になり、左端のプレフィックスルールに違反します
2)インデックス列で操作(計算、関数、型変換)を実行すると、インデックスが失敗し、全表スキャンになります。
3)ストレージエンジンは、インデックスの範囲条件の右側にある列を使用できません。たとえば、次のようになります。selectid、name from student where id> 50 and name = 'Zhang San'、これにより名前インデックスが失敗します
4)カバーリングインデックスを使用してみてください。*を選択しないでください。
5)MySQLは、インデックスが(!=または<>)に等しくない場合、インデックスを使用できません。そのため、テーブル全体がスキャンされます。理由も非常に単純です。B+ Treeリーフノードはポインターで接続され、並べ替えられます。 。このデータ構造は、この種のインデックスクエリを使用できないことを意味しないように、整然とした固定値クエリのみを解決できます。
6)ISNULLおよびISNOT NULLは、上記と同じ理由でインデックスを使用できません
7)一重引用符のない文字列のインデックスが無効です
8)またはに接続すると、インデックスは失敗します
7.8 InnoDBが主キーを作成する必要があるのはなぜですか?
InnoDBの場合、主キーインデックスを手動で作成しない場合でも、B + Treeは作成するインデックスに依存する必要があるため、基盤となるMySQLは、テーブル全体のすべてのデータを維持するためのクラスター化インデックスの作成に役立ちます。InnoDBが主キーを構築する必要があるのはなぜですか?独自のデータベースのリソースは非常に貴重であるため、手動で実行できることを維持するためにMySQLに問題を起こしてはなりません。率直に言って、データベースのオーバーヘッドを削減することです。
7.9 整数の主キーを使用することが推奨されるのはなぜですか
例としてUUIDを取り上げましょう。非常に長いが意味のない文字列の大きな文字列。上記のInnoDBのインデックスグラフを振り返ると、2つのintデータを比較する方が速いですか、それとも2つの文字列を比較する方が速いですか。何も考えずに、2つのint型を比較する方が間違いなく有利です。文字列を少しずつ比較する必要があります。2つの文字列の最後の桁だけが矛盾している場合でも、悪いことではありません。
7.10 自動インクリメントの主キーを使用することが推奨されるのはなぜですか
上記のB + Treeの3番目の機能:リーフノードは、インターバルアクセスのパフォーマンスを向上させるためにポインターで接続されています。これにより、SQLの行などの範囲検索という利点がもたらされます。select* from tablename where id between 1 and 20、MySQLは、インデックスが1に等しい位置を検索し、次に20の位置を検索するだけで済みます。リンクリストをめくると、その間の最初と最後の位置が、見つける必要のある結果セットです。しかし、これも問題を引き起こし、主キーが1、2、3、4、6、7に挿入され、この時点で5が挿入されていることを追加します。MySQLはインデックスを維持するときに元のリンクリストの順序を壊し、結果としてリンクリストでは、ノードが分割および再配置されるため、パフォーマンスが低下します。
7.11InnoDBの非主キーインデックスが主キー値を格納する理由
一貫性を維持するために、データベーステーブルがDML操作を実行すると、非主キーインデックスが主キーの値を保存し、変更する必要がないため、同じレコード行のページアドレスが変更されます。同時に、Innodbデータ自体が主キーインデックスが配置されているB +ツリーに集約されているため、ストレージスペースを節約することもできます。通常のインデックスがデータの別のコピーを格納し続けると、同じ数のコピーが生成されます。インデックスがあるのでデータの。
7.12B-Treeの代わりにB + Treeを使用する理由
B + Treeはすべてのデータをリーフノードに格納し、すべての非リーフノードは冗長インデックスを格納するために使用されます。これにより、B + Treeの高さを決定するのは非リーフノードであるため、非リーフノードはより多くのインデックスを格納できます。 。非リーフノードがより多くの値を格納できる場合、ツリーの全体の高さが減少し、それによってディスクIOの数が減少し、システム消費が減少します。
8.インデックスマインドマップ
この記事の構成は次のとおりです。https: //www.bilibili.com/video/BV1xh411Z79d?p = 3
https://www.jianshu.com/p/ac12d2c83708
https://www.cnblogs.com/guokaifeng/p/11272896.html
https://www.cnblogs.com/boothsun/p/8970952.html#autoid-6-0-0