インデックスは、基礎となる実装に応じて B ツリー インデックスとハッシュ インデックスに分類できます。ほとんどの場合、B を使用します。 - ツリー インデックス - ツリー インデックスは、パフォーマンスと機能が優れているため、同時実行性の高いシステムの構築に適しています。
インデックスの保存方法に応じて、インデックスはクラスター化インデックスと非クラスター化インデックスに分類できます。非クラスター化インデックスのリーフ ノードにはすべてのフィールドと主キー ID のみが含まれますが、クラスター化インデックスのリーフ ノードには完全なレコード行が含まれます。
クラスター化インデックスと非クラスター化インデックスに応じて、通常のインデックス、カバリング インデックス、ユニーク インデックス、ジョイント インデックスにさらに分類できます。
クラスター化インデックスはクラスター化インデックスとも呼ばれますが、実際には別のインデックス タイプではなく、データ ストレージ方式の 1 つです。インデックスには、レコードの行のすべての列情報が格納されます。つまり、クラスター化インデックスのリーフ ノードには完全なレコード行が含まれます。
非クラスター化インデックスは、補助インデックスおよび通常のインデックスとも呼ばれます。そのリーフ ノードには、主キー値が 1 つだけ含まれています。非クラスター化インデックスを通じてレコードを検索するには、まず主キーを見つけてから、次の場所に移動する必要があります。主キーを使用してクラスター化インデックスを作成し、対応するレコード行を検索します。このプロセスはテーブル リターンと呼ばれます。
たとえば、ユーザー名と年齢を含むデータ テーブルの場合、主キーがユーザー ID であると仮定すると、クラスター化インデックスの構造は次のようになります (オレンジ色は ID を表し、緑色は子ノードへのポインターです)。 :
リーフノードでは、レコードを強調表示するために (id, name, age)
を区別していますが、実際にはつながっています。一緒に並んで、レコード全体として。
非クラスター化インデックス (インデックスとして年齢を使用) の構造は次のとおりです。
年齢フィールド自体に加えて、ノードには、現在のレコードの主キー ID のみが含まれ、完全なレコードの情報は含まれません。レコード データの行全体を取得するには、ID 番号を使用してクラスター化インデックスをクエリする必要があります。
InnoDB では、各テーブルにクラスター化インデックスが必要です。クラスター化インデックスは、デフォルトで主キーに基づいて作成されます。テーブルに主キーがない場合、InnoDB はクラスター化インデックスとして適切な列を選択します。適切な列が見つからない場合は、非表示の列 DB_ROW_ID がクラスター化インデックスとして使用されます。
非クラスター化インデックスには完全なデータ情報が含まれていないため、完全なデータ レコードを検索するにはテーブルを返す必要があるため、1 つのクエリ操作で実際には 2 つのインデックス クエリが必要になります。結果を取得するためにすべてのインデックス クエリを 2 回実行する必要がある場合、クエリを 1 つ削減できる場合は 1 つ削減する必要があるため、必然的に効率の低下につながります。
上記の年齢インデックスを例に挙げます。これは非クラスター化インデックスです。年齢別にユーザー ID をクエリしたい場合は、次のステートメントを実行します。
1 |
年齢 = 10 のユーザー情報から ID を選択; |
この場合でもテーブルを返す必要がありますか? id の値だけが必要なので、age インデックスを通じて id を取得できますが、それでも一度テーブルに戻ってしまうのは無駄な操作ではないでしょうか。実際、それは必要ありません。補助インデックスにクエリに必要なすべての情報がすでに含まれている場合、インデックス クエリでテーブルを返す操作を回避できます。これはカバリング インデックスです。
ジョイント インデックスは、複数の列に対して同時に作成されたインデックスを指します。ジョイント インデックスを作成した後、リーフ ノードには、各インデックス列の値が含まれます。列のソート、このソートは辞書の順序として理解されているものと似ています。
たとえば、上記の名前と年齢に対して同時に作成されたインデックス構造:
(名前, 年齢)
両方 これは略語であり、名前は十数個思いつきません。
各リーフ ノードは、すべてのインデックス列を同時に保存します。さらに、主キー ID のみが含まれます。
複数の列に対してインデックスが作成される場合、インデックスが作成された列が含まれている限り、そのインデックスは使用できません。左端のプレフィックス マッチング原則に従います。
列 (A、B、C) にインデックスが作成されていると仮定すると、次のシナリオでのみインデックスを使用できます。
#列 (A、B、C) の場合C)/( A, C) または (A, B) をクエリするとインデックスと一致しますが、そのインデックスは (C, A) または (B, C) には使用できません。
ワイルドカードは、LIKE '%VAL%' ではなく、LIKE 'val%' の形式でのみ使用できます。これにより、テーブル全体のスキャンが発生します。
インデックス列は操作できません。たとえば、WHERE A 1 = 5 ではインデックスが失敗します。
インデックス列には、LIKE/BETWEEN/>/
インデックス列には NULL 値を含めることはできません。
MySQL の新しいバージョン (5.6 以降) では、インデックス プッシュダウン メカニズムが導入されています。インデックス トラバーサル プロセス中に、インデックス プッシュダウンはフィールドによって判断されます。まず、条件を満たさないレコードが直接フィルターで除外され、テーブルが返される数が減ります。
たとえば、上記のテーブルで (名前, 年齢) の結合インデックスを作成します。通常のクエリ ロジックは次のとおりです:
対応する主キー ID を検索します。名前を介して
ID レコードの列に基づいて年齢条件を照合します
このアプローチでは、多くの不要なテーブルが返されます。たとえば、 、 (Zhang San、10) および (Zhang San、15) 次に、(Zhang San、20) のレコードをクエリしたいと思います。クエリを実行するときは、まず Zhang San を通じて条件を満たすすべての主キー ID を見つけてから、クラスター化インデックス内の条件を満たす行を走査して、age = 20 に一致するレコードがあるかどうかを確認します。実際には、条件を満たすレコードは存在しないため、このテーブルの返却処理は無駄とも言えます。
インデックス プッシュダウンの主な機能は、これを改善することです。結合インデックスでは、最初にテーブルに返す必要のないレコードを名前と年齢で除外し、次にテーブルに戻ってクエリを実行します。インデックスを使用してテーブルの戻り数を減らします。
ユニークインデックスとは、同一のインデックス値を許容しないインデックスであり、インデックス作成時にシステムにより重複キー値が存在するかどうかがチェックされます。インデックスが更新または追加されます。これはロギング時にチェックされます。主キーインデックスは一意のインデックスです。
以上がMySQL のクラスター化インデックス、非クラスター化インデックス、結合インデックス、および一意のインデックスとは何ですかの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。