MySQL複合インデックスの概要

MySQL複合インデックスの概要

1. 背景

最近、遅い SQL ステートメントによってシステム パフォーマンスの問題が頻繁に発生するようになったため、インデックスを最適化することにしました。一部のテーブル構造にはすでに多くのインデックスがあります。インデックスを追加し続けると、必然的にデータ挿入のパフォーマンスに影響します。では、複合インデックスを使用して目標を達成することは可能でしょうか? この記事で見てみましょう。

2. 複合インデックスを理解する

where条件で複数のフィールドが使用され、複数のフィールドにインデックスを付ける必要がある場合は、複合インデックス (結合インデックス) の使用を検討できます。たとえば、住所を検索する場合、都道府県と市区町村を入力する必要があります。この場合、都道府県と市区町村にインデックスを作成すると、データ量が多いときにクエリ速度が大幅に向上します。

複合インデックスの利点は何ですか?

  • クエリのオーバーヘッドを削減:複合インデックス (c1、c2、c3) を作成することは、実際には 3 つのインデックス (c1)、(c1、c2)、(c1、c2、c3) を作成することと同じです。大きなテーブルの場合、これによりオーバーヘッドが大幅に削減されます。
  • カバーリング インデックス: MySQL はテーブルに戻らずにインデックスをトラバースしてデータを直接取得できるため、ランダム IO 操作が大幅に削減されます。
  • 高効率:インデックス列の数が多いほど、インデックスを通じてフィルターされるデータが少なくなり、クエリの効率が向上します。

欠点:

  • インデックス フィールドの数が増えると、作成されるインデックスの数も増え、インデックスごとにディスク領域のオーバーヘッドが増加します。
  • インデックスの数が多いほどクエリの効率は高くなりますが、インデックスの更新に必要な追加、削除、変更操作の効率にも影響します。

複合インデックスの使用に関する推奨事項: 1 つのテーブルに複数の複合インデックスを含めないでください。また、1 つの複合インデックスに 3 つ以上のフィールドを含めないでください。それを超過した場合は、必要性と他の代替手段があるかどうかを検討する必要があります。

3. 左端一致原則

複合インデックスは、左端一致の原則に従います。名前が示すように、複合インデックスでは、左端のフィールドが最初に一致します。したがって、複合インデックスを作成するときは、 where句で最も頻繁に使用されるフィールドが複合インデックスの左端に配置されます。

補助インデックスはB+ツリーで実装されています。複数の列を指定できますが、各列の比較優先順位は異なり、前に書いた方が優先順位が高くなります。一度省略が発生すると、B+ ツリー上で検索を続行することができないため (ギャップを埋めるなどの手段で解決しない限り)、最も左の連続一致に従って検索が実行されます。検索は B+ ツリー上で行われるため、条件の比較には当然、完全一致 (つまり、「=」と「IN」) が必要になります。

where句では 2 つのフィールド c1 と c2 が使用されています。インデックスを作成するとき、2 つのフィールドの順序は (c1, c2) とすべきでしょうか、それとも (c2, c1) とすべきでしょうか。

正しいアプローチは、重複値が最も少ないものを最初に置くことです。たとえば、値の 95% が一意である場合は、それらを先頭に配置することを検討できます。

4. フィールド順序の影響

複合インデックスは左端一致の原則に従いますが、 whereクエリ条件のフィールドもインデックスの順序で記述する必要がありますか?

たとえば、複合インデックスが (c1、c2、c3) の場合、次の 2 つのクエリ条件はインデックスに影響しますか?

c1 = 1 かつ c2 = 4 の場合、t_user から * を選択します。 
c2 = 4 かつ c1 = 1 の場合、t_user から * を選択します。 


最初の SQL ステートメントの方が効率的だという記事を見ました。これは信用できますか? 2 つのクエリ メソッドの条件は同じで、結果も同じになるはずです。通常、 Mysqlでは同じインデックスを使用できます。

Mysqlのクエリ オプティマイザexplain使用して上記の 2 つのステートメントを分析すると、実行プランがまったく同じであることがわかります。つまり、SQL ステートメント内のフィールドの順序は複合インデックス フィールドの順序と一致する必要はなく、クエリ オプティマイザーによって順序が自動的に調整されます。

効率に影響があるとすれば、それはおそらくクエリ オプティマイザの修正順序の影響であり、これはほとんど無視できる程度です。

5. 単一のフィールドでインデックスをトリガーできますか?

複合インデックス (c1,c2,c3) は、3 つのインデックス (c1)、(c1,c2)、(c1,c2,c3) に相当しますが、クエリ条件に c1 のみが含まれている場合、そのインデックスが使用されることは明らかです。

しかし、where 条件が次のようになっている場合はどうなるでしょうか。

c2 = 4 の場合の t_user から; 


上記のステートメントはインデックスを使用しますか? これはいくつかの状況で説明できます。

条件として explan query c1 を使用して SQL ステートメントを実行します。

c1 = 1 の場合の t_user からの * を選択します。 


上記のステートメントのインデックス タイプは ref です。 ref タイプは、MySQL がインデックス内のすべてのデータをスキャンして判断することなく、特定のアルゴリズムに基づいて条件を満たすインデックスをすばやく見つけることを意味します。データをすばやく見つけるには、このタイプのインデックスが特定のデータ構造を満たしている必要があります。

条件として explan query c2 を使用して SQL ステートメントを実行します。

c2 = 4 の場合、t_user から c2 を選択します。 


上記のステートメントのインデックス タイプはindexです。 indexタイプは、 Mysqlインデックス全体をスキャンすることを意味します。インデックスまたはインデックスの一部である限り、 Mysqlそれをインデックス タイプでスキャンする可能性があります。この方法ではデータを 1 つずつ検索するため、パフォーマンスはあまり高くありません。

この例では、クエリ対象のフィールドに特定の要件があります。 whereの条件は c2 であり、 selectでクエリ対象のフィールドは c2 のみであるため、 indexタイプ index が使用されます。

c2 が * または他のフィールドに置き換えられた場合:

c2 = 4 の場合の select * from t_user の説明 


上記のステートメントでは、インデックスが使用されなくなったことがわかりますが、テーブル全体のスキャンが実行されます。これは、MySQL が左端一致の原則に従う理由も説明しています。

結論は次のようになります。単一のフィールドが複合インデックスの最初のフィールドである場合、インデックスは通常どおり使用されます。単一のフィールドが複合インデックスの別のフィールドであり、このフィールドのみがselect後に出現する場合は、 indexタイプ index が使用されます。それ以外の場合は、フル テーブル スキャンが使用されます。

7. 複合インデックスは単一のインデックスを置き換えることができますか?

単一インデックス:

(c1)、

複合指数:

(c1、c2)。

クエリ条件として c1 を使用すると、単一インデックスのクエリ速度は複合インデックスのクエリ速度とほぼ同じか、複合インデックスよりもわずかに速くなります。

複合クラスター化インデックスの開始列以外の列 (c2) のみをクエリ条件として使用した場合、複合インデックスは効果がありません。

テーブルに複合インデックス (c1、c2) がある場合は、単一のインデックス (c1) を作成する必要はありません。

単一のインデックス (c1) がすでに存在する場合、クエリで必要な場合は、複合インデックス (c1、c2) を追加して効率を向上させることができます。

まとめ:

この記事では、MySQL 複合インデックスを使用する際に注意すべきいくつかの知識ポイントをまとめています。使用時には、explain を使用して、SQL 文がインデックスを使用しているかどうか、またどのインデックスを使用しているかを確認できます。

ただし、Mysql の実行プランとクエリの実際の実行プロセスは完全には一致しないことを理解する必要があります

なぜ私がこれを知っているのかと聞かないでください。実際にこれに遭遇したからです。同じ SQL ステートメントでも、クエリ条件に応じてインデックスが使用される場合と使用されない場合があります。

MySQL複合インデックスの概要に関するこの記事はこれで終わりです。MySQL複合インデックスに関するより関連性の高いコンテンツについては、123WORDPRESS.COMの過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。今後とも123WORDPRESS.COMをよろしくお願いいたします。

以下もご興味があるかもしれません:
  • MySQL インデックス無効化の暗黙的な変換の問題
  • MySQL の複合インデックスはどのように機能しますか?
  • MySQL のインデックスの原理とクエリの最適化の詳細な説明
  • MySQLデータベースインデックスの詳細な紹介
  • MySQLデータベースインデックスの詳細な説明
  • MySQL データの最適化 - 多層インデックス
  • MySQLインデックスの実装方法

<<:  Vueリクエストインターセプターの設定方法の詳しい説明

>>:  CSS3を使用して背景画像の色を変更するさまざまな方法

推薦する

CentOS 6-7 PHPのyumインストール方法(推奨)

1. 現在インストールされているPHPパッケージを確認するyum list installed |...

Windows サーバー ポートを開きます (例としてポート 8080 を使用します)

ポートとは何ですか?私たちが通常参照するポートは、物理的な意味でのポートではなく、具体的には TCP...

Centos7 での nginx のインストールと設定に関する詳細なチュートリアル

注: ソフトウェアのインストールの基本ディレクトリ パスは /usr/local です。ソフトウェア...

MySQL query_cache_type パラメータと使用方法の詳細

MySQL クエリ キャッシュを設定する目的は次のとおりです。クエリ結果をキャッシュしておくと、次回...

Dockerコンテナを外部IPとポートにバインドする方法

Docker を使用すると、外部からコンテナにアクセスしたり、コンテナを相互接続したりすることで、ネ...

SSL を実装するために nginx を設定する方法の例

環境説明サーバーシステム: Ubuntu 18.04 64ビットnginx: 1.14この記事では主...

mysql 5.7.5 m15 winx64.zip インストール チュートリアル

win7 64 ビットで mysql-5.7.5-m15-winx64 をインストールして構成する方...

TomcatはNginxリバースプロキシのクライアントドメイン名を取得します

質問Nginx リバース プロキシの後、Tomcat アプリケーションは、クライアント ブラウザーの...

配列をフィルタリングするJavaScript

この記事では、配列フィルタリングを実装するためのJavaScriptの具体的なコードを参考までに紹介...

React で遅延読み込みを使用して最初の画面の読み込み時間を短縮する方法

目次使用インストールルーティングでどのように使用しますか?読み込み速度の比較最近、中間およびバックエ...

Linuxでテキスト比較を実現するコツを教えます

序文コードを書く過程で、必然的にコードに何らかの変更を加えることになります。しかし、変更を加えるとき...

OR キーワードを使用した MySql 複数条件クエリ ステートメント

前の記事では、And キーワードを使用した MySql の複数条件クエリ ステートメントを紹介しまし...

Web プロジェクト開発における 2 つのトークン理由とサンプル コードの分析

目次質問:プロジェクトには 2 つのトークンがあり、1 つは有効期間が 2 時間 (ショート トーク...

MySQL マスタースレーブレプリケーションの原理からインストールと設定までを包括的に解説します。

マスタースレーブレプリケーションがなぜ必要なのでしょうか? 1. 複雑な業務システムでは、SQL 文...