[MySQL] MySQLインデックスの左端のプレフィックス最適化

1. ジョイントインデックス

主キーに設定されたインデックスをクラスタードインデックス、通常のフィールドに設定されたインデックスをセカンダリインデックスと呼び、複数の通常のフィールドを組み合わせて作成されるインデックスを結合インデックスと呼び、複合
インデックスとも呼ばれます
。ジョイント インデックス、注意が必要です (a,b,c) と (b,a,c) は使用時に異なるジョイント インデックスを持つため、複数のフィールドの順序に注意する必要があります。
ジョイント インデックスの使用は、左端のプレフィックスに従う必要があります。一致原則、つまり、左端の最初の方法に従います。

統合インデックス実行の例

(a,b,c) の結合インデックスを作成し、発生する可能性のあるすべての状況の例を示し、インデックスが実行されるかどうかを記述します。

Where ステートメント インデックスが使用されているかどうか
ここで、a = 1Y、 に使用する
ここで、a = 1 および b = 2 Y、a、bに慣れています
ここで、a = 1、b = 2、c = 3 Y、a、b、c に慣れています
ここで、a = 1、b は 'kk%' のように、c = 3 Y、a、b、c に慣れています
ここで、a = 1、b は '%kk' のように、c = 3 Y、のみを使用してください
ここで、a = 1、b は '%kk%' のように、c = 3 Y、のみを使用してください
ここで、a = 1、b は「k%kk%」のように、c = 3 Y、a、b、c に慣れています
ここで、a = 1 および c = 3 A は使用されていますが、c は許可されておらず、b は中断されています
ここで、a = 13、b > 2、および c = 3 a と b を使用します。c は範囲外では使用できません。b は壊れています。
ここで、a は null であり、b は null ではありません is null はインデックスをサポートしますが、is not null はサポートしません。そのため、a はインデックスを使用できますが、b はインデックスを使用できない可能性があります (8.0)
b = 2 または b = 3 および c = 4 または c = 4 N
ここで、<> 1 は、abs(a) =1 のインデックスを使用できません。 インデックスは使用できません
b = 2 ではインデックスを使用できません (c = 3)。 インデックスは使用できません
ここで、b = 2 および c = 3 インデックスは使用できません

クエリ オプティマイザーにより、where 句内のフィールド a の順序は重要ではありません。

2. 最適化によるインデックス順序

MySQLでの並べ替え

MySQL には 2 つの並べ替え方法があります。

  • ファイルソートの使用: テーブル インデックスまたはフル テーブル スキャンを通じて、条件を満たすデータ行を読み取り、ソート バッファー ソート バッファーでソート操作を完了します。インデックスを介してソート結果を直接返さないすべてのソートが呼び出されます。ファイルソートの使用
  • インデックスを使用: 順序付けされたインデックスを順次スキャンすることで、順序付けされたデータが直接返されます。この場合、インデックスを使用するため、追加の並べ替えは必要なく、操作効率が高くなります。

当然、Using インデックスはインデックスを使用するのでパフォーマンスが高くなければなりませんので、実際に使用する際に SQL を using インデックスに最適化してみます

データの準備

テスト データの場合は、多ければ多いほど良いため、データ量が 2w の
ロール テーブルのテーブルを準備します。

  • ID:自己成長
  • role_name: ランダムな文字列、繰り返しは許可されません
  • 注文: 1-1000 任意の数
    ここに画像の説明を挿入

インデックスなし

ここでは、誰もがよく知っている Explain コマンドを使用します。

Explain コマンドは主に SQL の実行計画を表示するために使用され、SQL クエリー・ステートメントを実行するオプティマイザーをシミュレートできます。

現在、ロールテーブルにはインデックスがありません
ここに画像の説明を挿入

次に、次の SQL ステートメントを実行して、インデックスなしの場合とインデックスありの場合をそれぞれ表示します。

explain select * from role order by orders

ここに画像の説明を挿入

この時点で、並べ替えに使用される条件付き順序ではインデックスが使用されないため、インデックスは並べ替えバッファを使用する、つまりデータを読み取り、並べ替えバッファで並べ替えた後に表示することがわかります。

インデックス付き

このとき、ロールテーブルにインデックスを追加します。

-- 给tb_user中的age和phone创建索引 
-- CREATE INDEZ 索引名 ON 表名(字段名...);
CREATE INDEX or_role ON role(orders,role_name);

ここに画像の説明を挿入

これで、必要なインデックスが作成され、前の SQL ステートメントが再実行されました。

explain select * from role order by orders, role_name

今回はExtraに「Using Index」と表示されており、インデックスを使用していることがわかりますが、同時に、今回は前に作成したインデックスであるordersとrole_nameの2つの並べ替えフィールドを使用していることに注意してください。ご存知のとおり、MySQL には独自の実行オプティマイザーがあり、where 句のインデックス フィールドの位置は、それが使用されている限り無関係ですが、order by の場合も同じでしょうか。

Where 句のインデックス フィールドの順序が一貫していません

explain select * from role where orders = 500 and role_name like 'a%'

ここに画像の説明を挿入

言っておきますが、知らなくても大丈夫です、写真と真実があります

インデックスフィールドの順序による順序が一貫していません

explain select * from role order by role_name,orders

次に、order by 句のフィールドの順序がインデックスの順序と一致しない場合を見てみましょう。
ここに画像の説明を挿入

ご覧のとおり、最終的には filesort を使用している状況が依然として表示されました。

インデックスフィールドの昇順と降順が一致しない

explain select * from role order by orders asc, role_name desc

ここに画像の説明を挿入

order by を使用する場合、順序を指定しない場合、デフォルトは昇順であり、インデックスは同じです。フィールドはデフォルトでは昇順ですが、クエリを実行すると、1 つは昇順、もう 1 つは降順になります。この問題を解決したい場合は、次の SQL ステートメントを使用して、インデックスを生成するときにインデックスの順序を指定できます。

CREATE INDEX or_role ON role(orders asc,role_name desc);

3. まとめ

ジョイント インデックスを使用する場合は、where 句で左端のプレフィックス インデックスが使用されているかどうかを考慮して、合理的にインデックスを作成する必要があります。MySQL にはオプティマイザがあるため、where 句内のフィールドの順序を考慮する必要はありません。 order by で結合インデックスを使用する場合、order by フィールドがインデックスの順序と一致しているか、照合順序がインデックスと一致しているかを考慮する必要があります。

おすすめ

転載: blog.csdn.net/u011397981/article/details/130678672