索引付きデータ構造:B+ツリー
B+ツリー検索プロセス
たとえば、29を見つけるために、最初のディスクIOはディスクブロック1をメモリにロードし、メモリ内でそれを2等分してP2を決定します。 2番目のディスクIOはディスクブロック3をメモリにロードし、3番目のディスクIOはディスクブロック8をメモリにロードし、それを2等分して29を見つけます。 3層のB+ツリーは数百万のデータを表現することができ、これは大きな性能向上です。
インデックスの原則
- mysqlは、マッチングを停止する範囲クエリに遭遇するまで、右にマッチングし続けます。例えば、a = 1とb = 2とc > 3とd = 4シーケンシャルインデックスを構築する場合、dはインデックスに使用することはできませんが、インデックスを構築する場合は使用することができ、a、b、dの順序は任意に調整することができます。
- インデックスの構築はどのような順序でも可能で、mysqlのクエリオプティマイザがインデックスが認識できる形に最適化する手助けをしてくれます。
- インデックスのために最も識別力のある列を選択します。
- インデックスされたカラムは計算に関与できません。
- 例えば、元々aのインデックスがあり、インデックスを追加する場合、元のインデックスを修正するだけで済みます。
インデックスの失敗
- 条件内に or がある場合、条件の1つにインデックスがあっても、そのインデックスは使用されません。 注意: or を使用してインデックスを有効にするには、or 条件の各カラムにインデックスを付けるだけです。
- 最初に使用された部分以外の複数列インデックスでは、そのインデックスは使用されません。
- likeこのクエリは%
- データ型の変換
例:select * from sunyang where id='123'; カラムタイプが文字列の場合、それは引用符を使用して引用されるデータの条件にする必要があります、そうでなければ、インデックスを使用しないでください。
mysql がフルテーブルスキャンを使用する方がインデックスを使用するよりも高速であると推定した場合は、インデックスを使用しないでください。
- 列対インデックス
2つのカラムが別々のインデックスを持つテーブルでは、以下のクエリ条件はインデックスに移動しません。
select * from test where id=c_id;
この状況は、フルテーブルスキャンを行うよりも悪いと考えられます。
- ヌル値 の存在
カラムがNULL可能な場合、インデックスは作成されない。
- not条件
<>NOT、not exitsなどの条件は見つけるのが難しく、フルテーブルスキャンを好む。
- この条件には、加算、減算、乗算、除算などの関数や演算が含まれる。
select * from test where upper(name)='SUNYANG';