1. ホーム
  2. データベース
  3. マイサク

ジョイントインデックスのためのmysqlの条件とインデックスが失敗するための条件

2022-01-06 09:27:51

1. 連合体インデックスが失敗する条件

連合体インデックスは複合インデックスとも呼ばれます。2つ以上の列に対するインデックスは、複合インデックスと呼ばれます。

複合インデックスの場合。Mysql はインデックス内のフィールドを左から右に使用し、クエリはインデックスの一部、ただし左端の部分のみを使用することができます。例えば、インデックスがキーインデックス(a,b,c)であるとする。これは、a | a,b| a,b,c 3つの組み合わせのルックアップをサポートできますが、b,cのルックアップはできません 。左端のフィールドが定数参照である場合、このインデックスは非常に有効である。 

    インデックスに追加の列を使用すると、検索を絞り込むことができますが、2つの列を持つインデックスを使用することは、2つの別々のインデックスを使用することとは異なります。複合インデックスは電話帳に似た構造で、人名は姓と名で構成されている。電話帳では、まず姓のペアでソートし、次に同じ姓を持つ人の名前のペアでソートします。姓が分かれば電話帳は非常に便利だが、姓と名が分かれば電話帳はもっと便利で、姓は分からないが名だけ分かれば、電話帳は役に立たない。

    ですから、複合インデックスを作成する際には、列の順番を慎重に検討する必要があります。複合インデックスは、インデックス内のすべての列、あるいは最初の数列を検索する場合に有効ですが、その後に続く列のいずれかだけを検索する場合には役に立ちません。

    例えば、名前、年齢、性別の複合インデックスを作成します。

    create table myTest(
         a int,
         b int,
         c int,
         KEY a(a,b,c)
    ).


(1) select * from myTest where a=3 and b=5 and c=4; ---- abc order
abcインデックスは3つともwhere条件の中で使用され、それぞれ役割を担っている

(2) select * from myTest where c=4 and b=6 and a=3;
whereの中の条件の順番は、クエリの前にmysqlによって自動的に最適化され、前の文と同じ効果があります。

(3) select * from myTest where a=3 and c=7;
aはインデックスを使用し、bは使用しないので、cはインデックスの効果で使用しない

(4) select * from myTest where a=3 and b>7 and c=3; ---- bの範囲値、ブレークポイント、ブロックされたcのインデックス
aは使用、bは使用、cは使用せず、ここbは範囲値で、インデックス自体を使用する以外はブレークポイントにもなっています

(5) select * from myTest where b=3 and c=4; --- ジョイントインデックスを順番に使用する必要があります。
a インデックスは使用されていないので、ここでは bc もインデックスの効果には使用されていません。

(6) select * from myTest where a>4 and b=7 and c=9;
aは使用されている bは使用されていない cは使用されていない

(7) select * from myTest where a=3 order by b. (7)のようになります。
aはインデックスを使用し、bも結果のソートにインデックスの効果を使用し、a以下の任意の段落のbは順序付けされる

(8) select * from myTest where a=3 order by c. (8) select * from myTest where a=3 order by c;
aはインデックスを使いますが、cは途中で切れてソートとして機能しないので、explainを使うとfilesortを見ることができます。

(9) select * from mytable where b=3 order by a;
bはインデックスを使用せず、aはソートでインデックスを使用しない

2. インデックス失敗の条件

  • インデックス列に対していかなる操作(計算、関数、(自動または手動)型変換)も行わない場合、インデックスは失敗し、フルテーブルスキャンに移行します。
  • ストレージエンジンは、インデックス範囲条件の右側の列を使用することができません
  • オーバーライドインデックス(インデックスのみにアクセスするクエリ(インデックスカラムとクエリカラムが一致する))を使用し、select *を減らすようにする。
  • not equal (! = または <>) を使用すると、mysql は動作しません。インデックスを使用すると、フルテーブルスキャンになります。
  • is null,is not nullもインデックスを使用できない ---- ここに疑問があるが、テストの後、それは動作する、refとconstレベル、すべてではない
  • のようにワイルドカード文字('%abc...')で始まる場合、mysqlのインデックスの失敗は、フルテーブルスキャン操作に変わるでしょう。質問です。like '%string%' のときにインデックスが使用されない場合の解決策?

シングルクォートのない文字列は、インデックスに失敗します。  

SELECT * from staffs where name='2000'; -- because mysql does an implicit type conversion at the bottom

SELECT * from staffs where name=2000; --- no indexes used

一般的な推奨事項

  • シングルキーインデックスの場合、現在のクエリに対してより良いフィルタリングを行うインデックスを選択するようにする。
  • 複合インデックスを選択する場合、現在のクエリに最適なフィルタリングを行うフィールドは、インデックスのフィールド順でできるだけ前方に配置する。
  • 複合インデックスを選択する際には、現在のクエリのwhere句からより多くのフィールドを含むことができるインデックスを選択するようにします。
  • 可能な限り、統計情報を分析し、クエリを微調整して、適切なインデックスを選択します。

mysqlのジョイントインデックスが有効になる条件と、インデックスが失敗する条件について、この記事が全てです。mysqlのジョイントインデックスが有効になる条件については、スクリプトハウスの過去記事を検索していただくか、引き続き以下の関連記事をご覧ください。