MySQL インデックス 15 問連続、あなたは何問解けますか?

目次

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

2. MySQL インデックスにはどのような種類がありますか?

3. インデックスはいつ無効になりますか?

4. インデックス作成に適さないシナリオはどれですか?

5. なぜ B+ ツリーを使用するのですか? なぜバイナリ ツリーを使用しないのですか?

6. B+ツリーインデックスツリー検索処理

7. 返品フォームとは何ですか? 返品フォームを減らすにはどうすればよいですか?

8. カバリングインデックスとは何ですか?

9. インデックスの左端の接頭辞の原則について話す

10. インデックスのプッシュダウンについて理解していますか? インデックスのプッシュダウンとは何ですか?

11. 大きなテーブルにインデックスを追加する方法

12. ステートメントでインデックス クエリが使用されているかどうかを確認するにはどうすればよいですか?

13. ハッシュ インデックスと B+​​ ツリーの違いは何ですか?

14. インデックスの長所と短所は何ですか?

15. クラスター化インデックスと非クラスター化インデックスの違い


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

インデックスは、データベース クエリの効率を向上させることができるデータ構造です。これは辞書のディレクトリと比較することができ、対応するレコードをすばやく見つけるのに役立ちます。
インデックスは通常、ディスク上のファイルに保存され、物理スペースを占有します。
ことわざにあるように、水は船を運ぶこともできますが、船を転覆させることもあります。適切なインデックスを使用するとクエリの効率が向上しますが、インデックスが多すぎるとデータベース テーブルの挿入および更新機能に影響を与えます。

2. MySQL インデックスにはどのような種類がありますか?

データ構造の次元

  • B+ ツリー インデックス: すべてのデータはリーフ ノードに格納され、複雑さは O(logn) で、範囲クエリに適しています。
  • ハッシュ インデックス: 同等のクエリに適しており、一度配置すると検索効率が高くなります。
  • フルテキスト インデックス: MyISAM と InnoDB は両方とも、フルテキスト インデックスの使用をサポートしています。フルテキスト インデックスは通常、テキスト タイプ char、text、および varchar で作成されます。
  • R ツリー インデックス: GIS データ型の SPATIAL インデックスを作成するために使用されます。

物理ストレージの寸法

  • クラスター化インデックス: クラスター化インデックスは、リーフ ノードのテーブルにデータを格納する主キーを使用して作成されるインデックスです。(Innodb ストレージ エンジン)
  • 非クラスター化インデックス: 非クラスター化インデックスは、非主キーを使用して作成されたインデックスであり、主キーとインデックス列はリーフ ノードに格納されます。(Innodb ストレージ エンジン)

論理次元

  • 主キー インデックス: null 値を許可しない特別な一意のインデックス。
  • 通常のインデックス: MySQL の基本的なインデックス タイプで、null 値と重複値が許可されます。
  • 結合インデックス: 複数のフィールドによって作成されたインデックスは、使用時に左端のプレフィックスの原則に従います。
  • 一意のインデックス: インデックス付き列の値は一意である必要がありますが、NULL 値も許可されます。
  • 空間インデックス: MySQL5.7 以降、空間インデックスがサポートされ、空間インデックスは OpenGIS 幾何学的データ モデルのルールに従います。

3. インデックスはいつ無効になりますか?

  • クエリ条件に or が含まれているため、インデックスが失敗する可能性があります
  • フィールドタイプが文字列の場合、where を引用符で囲む必要があります。そうしないとインデックスが失敗します。
  • ワイルドカードなどはインデックス障害を引き起こす可能性があります。
  • 結合インデックスの場合、クエリ内の条件列が結合インデックスの最初の列ではないため、インデックスは無効になります。
  • mysql の組み込み関数をインデックス列に使用すると、インデックスが無効になります。
  • インデックス列の操作 (+、-、​​、/ など) の場合、インデックスは無効になります。
  • (!= または <>、notin) をインデックス フィールドで使用すると、インデックスが失敗する可能性があります。
  • インデックス フィールドで is null と is not null を使用すると、インデックスが失敗する可能性があります。
  • 左結合クエリまたは右結合クエリに関連付けられたフィールドのエンコード形式が異なるため、インデックスが失敗する可能性があります。Mysql は、インデックスを使用せずにインデックスを使用するよりも、テーブル全体のスキャンを使用した方が高速であると推定しています。

4. インデックス作成に適さないシナリオはどれですか?

  • データ量が少ないテーブルはインデックス作成には適していません
  • 頻繁な更新はインデックス作成には適していません
  • 差別度の低いフィールド (性別など) はインデックス付けには適していません。グループ化、順序付け、その他のフィールドは後で使用されず、インデックス付けする必要がありません。
  • すでに冗長なインデックスが存在します (たとえば、a と b の結合インデックスがすでに存在しており、別のインデックスを作成する必要はありません)


5. なぜ B+ ツリーを使用するのですか? なぜバイナリ ツリーを使用しないのですか?

この質問は、クエリが十分に速いかどうか、効率が安定しているかどうか、保存されるデータの量、ディスク検索の数など、さまざまな側面から見ることができます。バイナリ ツリー、なぜ B ツリーではなく、B+ ツリーなのでしょうか?


なぜ一般的な二分木ではないのでしょうか?

バイナリ ツリーがリンク リストとして特殊化されている場合、それはテーブル全体のスキャンと同等になります。二分探索木と比較して、バランス二分木は検索効率がより安定し、全体的な検索速度が速くなります。

なぜバランスの取れた二分木ではないのでしょうか?

クエリの効率は、ディスク データよりメモリの方がはるかに速いことがわかっています。ツリー データ構造がインデックスとして使用される場合、データを検索するたびにディスクからノードを読み取る必要があります (これをディスク ブロックと呼びます)。しかし、バランスのとれたバイナリ ツリーには、1 つのキー値とデータごとに 1 つのキー値とデータのみが保存されます。 Bツリーであれば、より多くのノードデータを格納でき、ツリーの高さも低くなるため、ディスクの読み込み回数が減り、クエリ効率が速くなります。

では、なぜ B ツリーではなく B+ ツリーなのでしょうか?

  • B+ ツリーの非リーフ ノードはデータを保存せず、キー値のみを保存しますが、B ツリー ノードはキー値だけでなくデータも保存します。innodb のページのデフォルトのサイズは 16KB ですが、データが格納されていない場合は、より多くのキー値が格納され、対応するツリー (ノードの子ノード ツリー) の順序が大きくなり、ツリーが大きくなります。このようにして、ディスクのデータを見つけるために必要な IO の数が再び減り、データ クエリの効率が速くなります。
  • B+ツリーインデックスのデータはすべてリーフノードに格納され、データが順番に並べられて連結リストが結ばれます。次に、B+ ツリーを使用すると、範囲検索、ソート検索、グループ検索、重複排除検索が非常に簡単になります。

6. B+ツリーインデックスツリー検索処理

次のようなテーブル構造があり、これらのいくつかの教師データが初期化されているとします:

このクエリ SQL を実行するには、何回のツリー検索操作を実行する必要がありますか? 対応するインデックス ツリー構造図を描くことができます~

select * from Temployee where age=32;

idx_age の一般的なインデックス構造図はおおよそ次のとおりです。

 次に、次のように id 主キー インデックスのインデックス構造図を描画します。

 この SQL クエリ ステートメントの実行プロセスは次のとおりです
。idx_age インデックス ツリーを検索し、32<43 であるためディスク ブロック 1 をメモリにロードし、左の分岐を検索し、ディスク上のディスク ブロック 2 をアドレス指定します。

32<36 であるため、ディスク ブロック 2 をメモリにロードし、左の分岐を検索し、ディスク上のディスク ブロック 4 をアドレス指定します。

ディスク ブロック 4 をメモリにロードし、メモリのトラバースを続けて age=32 のレコードを見つけ、id = 400 を取得します。

id=400 を取得した後、id 主キー インデックス ツリーに戻り、id 主キー インデックス ツリーを検索し、ディスク ブロック 1 をメモリにロードします。300<400<500 であるため、中央のブランチを選択して、ディスクブロックをアドレス指定するdisk 3.

id=400 はディスク ブロック 3 で見つかりますが、リーフ ノードではないため、引き続き下を探します。ディスク ブロック 8 を指定するディスクへ。

ディスク ブロック 8 をメモリにロードし、メモリを走査して、id=400 のレコードを見つけ、行 R4 のデータを取得すれば完了です。

7. 返品フォームとは何ですか? 返品フォームを減らすにはどうすればよいですか?

クエリされたデータがインデックス ツリーに見つからない場合は、主キー インデックス ツリーに戻ってデータを取得する必要があり、このプロセスをテーブルに返すといいます。
たとえば、次のように SQL をクエリします。

全カラムのデータをクエリする必要があり、通常のidx_ageインデックスでは満たすことができず、主キーidの値を取得した後、主キーidの値に戻って検索して取得する必要があります。テーブルに戻ります。

8. カバリングインデックスとは何ですか?

SQL の select * をクエリし、それを select id、age に変更する場合、テーブルを返す必要はありません。id と age の値は両方とも idx_age インデックス ツリーのリーフ ノードにあるため、これにはカバー インデックスの知識が必要です。カバー インデックスは、インデックスに戻らずにインデックスからのみ取得できる
selet データ列です。つまり、クエリ列は構築されたインデックスによってカバーされます。

9. インデックスの左端の接頭辞の原則について話す

インデックスの左端のプレフィックス原則は、結合インデックスの左端の N フィールドにすることができます。たとえば、複合インデックス (a、b、c) を作成すると、実際には 3 つのインデックス (a)、(a、b)、(a、b、c) を構築するのと同等になり、インデックスの再利用機能が大幅に向上します。 。もちろん、左端のプレフィックスは、文字列インデックスの左端の M 文字にすることもできます。たとえば、通常のインデックス ツリーは次のようになります。

この SQL: select * fromemployee where name like 'small%' order by age desc; もインデックスにヒットします。

 

10. インデックスのプッシュダウンについて理解していますか? インデックスのプッシュダウンとは何ですか?

次の SQL が得られます。

 ここで、name と age は結合インデックス (idx_name_age) です。Mysql5.6 より前の場合は、idx_name_age インデックス ツリーで、最初の文字が「small」であるすべての人々を検索し、主キー ID を取得して、テーブルに戻ってデータ行を見つけ、年齢と性別を比較します。そして他の分野。図に示すように:

 友人の中には奇妙に思う人もいるかもしれません。idx_name_age (nameage) は結合インデックスではないでしょうか? 年齢をチェックして、「small」を含む単語を選択した後にテーブルに戻る方が効率的ではないのはなぜですか? そこで、MySQL 5.6 ではインデックス プッシュが導入されました。ダウン最適化では、インデックスの走査処理中にインデックスに含まれるフィールドをまず判定し、条件を満たさないレコードを直接除外し、テーブルに戻る回数を減らすことができます。
したがって、MySQL5.6 以降では、「小さい」を含む単語を選択した後、テーブルに沿って age=28 をフィルターします。

11. 大きなテーブルにインデックスを追加する方法

テーブルのデータ レベルが数千万を超える場合、このテーブルにインデックスを追加するにはどうすればよいですか? テーブルにインデックスを追加すると
、テーブルがロックされることを知っておく必要があります。慎重に操作しないと、生産事故が発生する可能性があります。以下の方法を参照できます。
1. まず、元のテーブル A と同じデータ構造を持つ新しいテーブル b を作成します。
2. 追加する必要がある新しいインデックスを新しいテーブル B に追加します
。 3. 元のテーブル A のデータをインポートします。新しいテーブル B への
名前の変更 新しいテーブル B は元のテーブルのテーブル名 A であり、元のテーブル A は別のテーブル名に置き換えられます。

12. ステートメントでインデックス クエリが使用されているかどうかを確認するにはどうすればよいですか?

Explain SQL 実行プランを表示して、インデックスがヒットしたかどうかを確認します。
SQL で Explain を使用すると、MySQL はステートメントの実行計画に関するオプティマイザーからの情報を表示します。

一般的に言えば、タイプ、行、フィルター済み、エクストラ、キーに焦点を当てる必要があります。

rows
この列は、必要なレコードを見つけるために読み取る必要がある行数を MySQL が見積もることを示します。InnoDB テーブルの場合、この数値は推定値であり、必ずしも正確な値ではありません。

filtered
この列はパーセンテージ値、つまり条件を満たすテーブル内のレコード数のパーセンテージです。簡単に言うと、このフィールドは、ストレージ エンジンから返されたデータをフィルター処理した後に条件を満たすレコード数の割合を示します。

type
type は接続タイプを示します。これは、インデックスのパフォーマンスを確認するための重要な指標です。次のパフォーマンスは降順です: system >const > eq_ref > ref > ref_or_null >index_merge > unique_subquery >index_subquery > range >index > ALLsystem: このタイプには、データベース テーブル内のデータが 1 つだけ必要です。これは、データベース テーブルの特殊なケースです。 const 型です。次は表示されません。
const: データは 1 つのインデックスを通じて検索できます。通常、主キーまたは条件としての一意のインデックスとして使用されます。このタイプのスキャンは非常に効率的で高速です。
eq_ref: 主キーまたは一意のインデックス スキャンに一般的に使用され、一般的に主キーを使用する関連クエリを指します。
ref: 一般的に非主キーおよび一意のインデックス スキャンに使用されます
。 ref_or_null: この接続タイプは ref に似ていますが、MySQL が追加でNULL 値を含む行の検索index_merge: インデックス マージ最適化メソッドが使用され、クエリで 3 つ以上のインデックスが使用されます。
unique_subquery: eq_ref と同様に、条件はサブクエリ内で使用します。index_subquery
: unique_subquery とは異なり、一意でないインデックスに使用され、重複した値を返す可能性があります。
range: 通常、範囲クエリに使用されます。たとえば、 between ... と or 操作中
インデックス: フル インデックス スキャン ALL: フル テーブル スキャン

extra
このフィールドには、MySQL によるクエリの解析方法に関するその他の情報が含まれており、通常は次の値を持ちます:
ファイルソートの使用: ファイルによるソートを示します。これは通常、指定されたソートがインデックスのソートと矛盾する場合にのみ表示されます。通常は order by ステートメントで表示されます。
インデックスの使用: カバーインデックスが使用されているかどうかを示します。一時テーブルの使用: 一時テーブルのパフォーマンスが特に低く、最適化する必要があるかどうかを示します。通常、group by ステートメントまたは Union ステートメントで見られます。Where を使用: Where 条件がフィルターに使用されることを示します。 Index 条件を使用: MySQL5.6 以降にプッシュされた新しいインデックス。データ フィルタリングはサービス層ではなくストレージ エンジン層で実行され、インデックスの既存のデータを使用してテーブルに返されるデータが削減されます。

キー
列は、実際に使用されるインデックスを示します。通常、これは可能なキー列と一緒に表示できます。

13. ハッシュ インデックスと B+​​ ツリーの違いは何ですか?

インデックスを設計するとき、どのように決めましたか?
B+ ツリーは範囲クエリを実行できますが、ハッシュ インデックスは実行できません。B+ ツリーは結合インデックスの左端の原則をサポートしますが、ハッシュ インデックスはサポートしません。
B+ ツリーはソートによる順序をサポートしますが、ハッシュ インデックスはサポートしません。
ハッシュ インデックスは、等価性クエリにおいて B+ ツリーよりも効率的です。(ただし、インデックスカラムに重複した値が多いとハッシュが競合して効率が悪くなります。)
B+ツリーでlikeを使ってファジークエリを実行すると、like以降の単語(%の先頭など)が再生されることがあります。最適化されたロールのため、ハッシュ インデックスはファジー クエリをまったく実行できません。


14. インデックスの長所と短所は何ですか?

利点:
インデックスにより、データ クエリが高速化され、クエリ時間が短縮されます。
一意のインデックスにより、データベース テーブル内の各行のデータの一意性が保証されます。欠点
:
インデックスの作成と維持に時間がかかります。
インデックスは、データ テーブルが占有するデータ領域。各インデックスも一定量の物理領域を占有します。
テーブル内のデータを追加、削除、変更する場合、インデックスも動的に維持する必要があります。

15. クラスター化インデックスと非クラスター化インデックスの違い

クラスター化インデックスは別個のインデックス タイプではなく、データの保存方法です。インデックス構造とデータが一緒に格納されるインデックスを表します。非クラスター化インデックスは、インデックス構造とデータが別々に格納されるインデックスです。
次に、さまざまなストレージ エンジンについて説明します。MySQL の InnoDB ストレージ エンジンでは、クラスター化インデックスと非クラスター化インデックスの最大の違いは、リーフ ノードがレコードの行全体を保存するかどうかにあります。クラスター化インデックスのリーフ ノードにはレコードの行全体が格納されますが、非クラスター化インデックスのリーフ ノードには主キー情報が格納されるため、一般的な非クラスター化インデックスでもテーブルに対してクエリを実行する必要があります。
テーブルにはクラスター化インデックスが 1 つだけ存在できます (一般的なクラスター化インデックスが主キー インデックスであるため)。テーブルには複数の非クラスター化インデックスが存在できます。一般に、クラスター化インデックス クエリは非クラスター化インデックス クエリよりも効率的です。クラスター化インデックス。フォームを返す必要がないためです。
MyISM ストレージ エンジンでは、データとインデックスが分離されており、リーフ ノードがアドレスを使用して実際のテーブル データを指すため、主キー インデックスと通常のインデックスは非クラスター化インデックスです。

参考文献: https://www.douyin.com/note/7196617563659406648

おすすめ

転載: blog.csdn.net/lwpoor123/article/details/130210993