Mysqlインデックスの基礎知識を詳しく解説

1. インデックスとは何ですか?

リレーショナル データベースでは、インデックスは、データ テーブル内の 1 つ以上の列を並べ替える別個のストレージ構造であり、テーブル内の 1 つ以上の列値のコレクションと、これらの値の物理識別子への対応するポインタです。テーブル内の論理ポインタのリスト。

実は書籍のカタログに相当するもので、カタログに従って必要なコンテンツをすぐに見つけることができます。

2. なぜインデックスを使用するのでしょうか?

実際には、データベース内のデータのアクセス速度を高速化するためです。

3. インデックスを使用するとアクセスが高速化されるのはなぜですか?

1. mysql クエリ データのパフォーマンスのボトルネックはどこにありますか?

mysqlのテーブルデータはディスク上に保存されており、使用する際にはディスクからメモリにデータをロードする必要があります。したがって、IO 操作がクエリ パフォーマンスのボトルネックになります。

2. ディスクからどれくらいのデータを取得する必要がありますか?

いいえ、ディスクとメモリ間の対話の最小論理単位はページ (dataPage) です。メモリは毎回ディスクから 1 つまたは整数倍のページを読み取ります。これはディスク先読みと呼ばれます。

ページ サイズはオペレーティング システムによって決まります (通常は 4k または 8k)。innoDB エンジンは毎回 16k データを読み取ります。

tips:磁盘预读背后的原理是——局部性原理

时间局部性:指的是同一个内存位置,从时间维度看来,它如果被引用了一次,那么较短时间内有很大可能被再次引用

空间局部性:指的是同一个内存位置,从空间维度看来,它如果被引用了一次,那么它附近的内存很大可能会被引用

3. インデックスはいつメモリにロードされますか?

インデックスはディスクに保存され、データのクエリを実行すると、最初にインデックスがメモリにロードされます。

4. インデックスにはどのような情報が保存されますか?

まず最初に、インデックスもテーブルであり、主キーとインデックス フィールドを保存し、エンティティ テーブル (実際のテーブル データ) のレコードをポイントしていることを理解する必要があります。

5. インデックスのデータ構造がハッシュ テーブルを使用しないのはなぜですか?

まず、ハッシュ テーブルに格納されている場合、Key はインデックス値、Value は対応するテーブル レコードになります。
ここに画像の説明を挿入します

  1. ハッシュの競合によりデータのハッシュが不均一になり、その結果、多数の線形クエリが発生し、時間の無駄が発生します。
  2. ハッシュ テーブル構造は範囲クエリをサポートしていないため、範囲クエリを実行する場合は、連続して検索する必要があります。
  3. すべてのインデックス テーブルをメモリにロードする必要があるため、メモリ スペースの要件は比較的高くなります。

しかし、メリットがないわけではなく、同等のクエリを実行する場合、ハッシュ テーブル構造のインデックスは非常に高速です。

Mysqlにハッシュインデックスはありますか?

① メモリエンジンが使用するハッシュインデックス

② innoDB エンジンは適応型ハッシュインデックスをサポート

6. MySQL が BST ストレージ インデックスを使用しないのはなぜですか?

BST: 二分探索木 各ノードの左側のサブツリーの値はノード値より小さく、各ノードの右側のサブツリーの値はノード値より大きくなります。

このルールに基づいて、二分探索法を使用してクエリ効率を向上させることができます。
しかし、テーブル内のデータが全体として増加または減少している状況を想像してください。その場合、二分探索ツリーはリンク リスト、つまり線形クエリに縮退します。

ここに画像の説明を挿入します

7. Mysql はインデックスの保存に AVL を使用しないのはなぜですか?

AVL: Balanced binary Tree. 最も短いサブツリーと最も長いサブツリーの高さの差は 1 を超えることはできません.

BST が使用されない理由は前述したように、AVL は実際には BST の劣化問題を解決しますが、ツリーのバランスを維持するために、データを挿入するときは、左折または右折する必要があります。本質的に、このソリューションは、クエリのパフォーマンスの向上と引き換えに挿入パフォーマンスの損失を利用します。

ビジネスで書き込みよりも多くの読み取りが必要な場合、この構造には特定の利点があります。読み取りと書き込みの数が同数の場合はどうなりますか? 解決策:
赤黒木

8. Mysql はなぜ赤黒ツリー ストレージを使用しないのですか?

赤黒ツリー: 自己平衡二分探索ツリー、効率的な探索ツリー

ここに画像の説明を挿入します

  1. 各ノードは赤または黒のいずれかです
  2. ルートノードは黒である必要があります
  3. 各リーフ ノード (リーフ ノードは、ツリーの最後にある NIL ポインターまたは NULL ノードを指します) は黒でなければなりません
  4. ノードが赤の場合、その子ノードは両方とも黒になります
  5. どのノードについても、リーフ ノード ツリーの終端にある NIL ポインターへの各パスには、同じ数の黒ノードが含まれます。上記の 5 つのプロパティにより、赤黒ツリーの最長のサブツリーが最短のサブツリーの

    2 倍を超えないことが保証され、回転数も一定のバランスを確保します。基本的にはクエリのパフォーマンスと挿入のパフォーマンスの妥協点です。ただし、まだ問題があります。データが増加するにつれて、

    ツリーの深さも増加します。つまり、回転数が増加することを意味します。 IO が増加し、パフォーマンスが低下します。

9. Mysql はインデックスの保存に B ツリーを使用しないのはなぜですか?

B ツリー: バランスの取れた多方向検索ツリーです。

ここに画像の説明を挿入します

B ツリーのプロパティ:
1. ルート ノードには少なくとも 2 つの子があります。
2. 各中間ノードには、k-1 個の要素と k 個の子が含まれます。ここで、ceil(m/2) ≤ k ≤ m 3. 各葉
ノードには、k-1 個の要素が含まれます。ここで、ceil(m/2) ≤ k ≤ m
4. すべてリーフ ノードは同じレイヤーに配置されます。
5. 各ノード内の要素は、小さいものから大きいものへと配置されます。ノード内の k-1 個の要素は、k 個の子に含まれる要素の値範囲の分割とまったく同じです。 6. 各ノードの構造は次のとおりです: (n,
A0 、K1、A1、K2、A2、…、Kn、An)
ここで、Ki (1≤i≤n) はキーワードであり、Ki<Ki+1(1≤i≤n-1) です。
Ai (0≤i≤n) は、サブツリーのルート ノードへのポインタです。そして、Ai が指すサブツリーのすべてのノードのキーワードは Ki+1 未満です。
n はノード内のキーワードの数であり、ceil(m/2)-1≤n≤m-1 を満たします。

ただし、データが各ノードに保存されていることがわかります。各キーとデータのサイズがポインター空間を除いて 1K であると仮定すると、innoDB は毎回ディスクから 16K のデータをフェッチします。つまり、一度にフェッチできるのは 16 個だけです.key+data、データが増加すると、B ツリーの深さも増加し、IO の数も増加します。

10. MySQL は B+ ツリーを使用してインデックスを保存します

B+ ツリーの特徴:

B+ ツリーのすべてのリーフ ノードは同じレベルにあり、リーフ ノードはポインタを介して接続され、順序付きリンク リストを形成します。これにより、範囲クエリが容易になります。
B+ ツリーの非リーフ ノードにはインデックス情報のみが格納され、特定のデータは格納されません。これにより、非リーフ ノードのサイズが削減され、メモリ使用率が向上します。

この点で、B+ ツリーはインデックスの格納において B ツリーよりも優れています。B+ ツリーの非リーフ ノードはデータを格納しません。そのため、より多くのポインタとインデックスを各ページに格納できます。B+ ツリーの方が分厚いです。 B ツリーよりも効果的に IO の数を削減します。また、B+ ツリーのリーフ ノードは二重リンク リスト構造であり、ランダムなクエリ データをサポートします。

注: 一般に、B+ ツリーの 3/4 レイヤーでほとんどのニーズを満たすことができます。それ以外の場合は、テーブルに分割する必要があります。
ここに画像の説明を挿入します

4. ストレージ エンジンとは何ですか?

ストレージ エンジンは、データの保存と取得を担当するデータベースのコンポーネントであり、データの保存、編成、アクセス方法を定義します。

1. Mysql はどのようなストレージ エンジンをサポートしていますか?

  • InnoDB: Mysql のデフォルトのストレージ エンジン。トランザクションのサポート、外部キーのサポート、フルテキスト インデックスのサポート、クラスター化インデックス (1 つのファイル内のインデックスとデータ) のサポート、行レベルのロックとテーブル ロックのサポートなど。
  • MyISAM: トランザクションをサポートしません、外部キーをサポートしません、フルテキスト インデックスをサポートします、クラスター化インデックスをサポートしません、非クラスター化インデックスをサポートします (インデックスとデータは同じファイル内にありません)、行レベルのロックをサポートしません、テーブルロックをサポートしますが、メモリ空間はサポートしません 要件は比較的高く、クエリは innoDB よりも高速です
  • メモリ: 永続性はサポートされていません。すべてのデータはメモリに保存され、一般的には使用されません。
  • CSV、アーカイブ、ブラックホール、NDB (MySQL Cluster)、マージ、フェデレーテッド、サンプル

2. Mysql のデフォルトの innoDB エンジンについて話しましょう

  • まず、Mysql の基本構造を見てみましょう。tips:mysql8.0之后Server层抛弃了缓存

ここに画像の説明を挿入します

  • innoDB は存在する必要があり、クラスタ化インデックスを 1 つだけ持つことができます。なぜですか? クラスター化インデックスが複数あるとデータの冗長性が発生するため(1つのクラスター化インデックスが1つのデータに対応する)、このクラスター化インデックスのキーが主キーとなり、主キーがない場合は一意キーとなります。一意のキーがない場合、innoDB はクラスター化インデックスのキーとして 6 バイトの ROWID を自動的に生成します。この ROWID はユーザーには表示されません。公式サイトからの説明は以下の通りです。
    ここに画像の説明を挿入します
  • 返品フォームとは何ですか?

これは、インデックスをクエリしてレコードの主キーを取得し、次にデータ テーブルをクエリして主キーを介して完全なレコードを取得するプロセスを指します。インデックス クエリを使用する場合、クエリされたフィールドがインデックスにない場合、クエリ結果にはインデックス フィールドのみが含まれており、クエリ結果を渡す必要がある 完全なレコードを取得するには、データ テーブルの主キーを再度クエリする必要があります。このプロセスがテーブル リターンです。テーブル リターン操作が実行されることがわかります

。データを取得するには主キーに従ってクラスター化インデックスに再度アクセスする必要があり、パフォーマンスの低下につながるため、IO 操作を追加します。

テーブルの戻り数を減らすために、カバリング インデックスを使用してテーブルの戻りを回避できます。カバリング インデックスとは、クエリに必要なすべてのフィールドがインデックスに含まれていることを意味するため、テーブルの戻り操作を通じてデータを取得する必要がなく、クエリのパフォーマンスが向上します。

以下に 2 つの例を示します。

select name,age from User where name=?;
#假设User表在name字段建立了普通索引,那么这个普通索引会指向主键id,然后根据主键id去聚集索引里面查找完整记录,返回。这就叫做回表。
select name,age from User where name = ? and age = ?;
#假设User表在name和age上建立了组合索引,那么查询的字段name和age就被索引全部覆盖了,直接查询这个组合索引就可返回数据,不需要再根据主键去聚集索引查完整记录,这就是覆盖索引

  • 主キーを設定するときに自分自身をインクリメントする必要がありますか?

データ挿入時のディスク ブロック分割を効果的に削減できる自動インクリメントを維持するようにしてください。ただし、自動インクリメント フィールドによりデータがクロールされやすくなり、最終的にはビジネス ニーズに依存します。

  • インデックスのプッシュダウンとは何ですか?

インデックス プッシュダウンは、データベース クエリのパフォーマンスを向上させるために使用される最適化テクノロジです。フィルタリング条件をストレージ エンジン レベルまでプッシュダウンし、ディスク IO 操作とデータ転送量を削減します。転送する必要があるデータ量の削減により、インデックスプッシュダウン プッシュすると、ネットワーク送信のオーバーヘッドも削減できます。

  • 一番左の一致は何ですか?

これは、クエリに複数列インデックスを使用する場合、インデックスの左端の列が最初に使用され、左端の列が等しい場合にのみ後続の列が使用されることを意味します。

例: User テーブルは、age フィールドにインデックスを作成します。

  1. select * from User where age = ? そして名前 = ?; //生效
  2. select * from User where name = ? and age = ?;//InnoDB エンジンの最適化が有効になると順序が変更されます
  3. select * from User where age = ?; //生效
  4. select * from User where name = ?;//失效

tips:组合索引的结构就是二元组

おすすめ

転載: blog.csdn.net/qq_56919740/article/details/132569154