インデックスの失敗と解決策

インデックス障害を引き起こす可能性のあるシナリオ

1.インデックス列は独立していません独立した手段:列を式の一部にすることも、関数のパラメーターにすることもできません

例:
where条件の左側に計算があります

explain
select * from employees where emp_no + 1 = 10003;

この時の説明はすべてです

解決:

where条件の右側に条件を変更します。

explain
select * from exployee where emp_no = 10003 -1;

この時の説明はconstです

2.左ぼかしを使用

例えば:

explain * from employees where first_name like '%Geo%'

解決策:
左側の接続の使用は避けてください。避けられない場合は、検索エンジンを使用して解決することを検討してください。

explain * from employees where first_name like 'Geo%'

3.を使用して照会された、または索引付けされていないフィールドの一部

例:first_nameにインデックスがあり、last_nameにインデックスがない場合、次のステートメントはインデックスを使用できません

explain
select * from employees where first_name = 'Georgi'
							or last_name = 'Georgi';

解決:

追加または条件付きインデックスを追加します。この時点で、データベースはデフォルトで2つのインデックスをマージし、全表スキャンを回避します。

4.文字列の状態は ''の使用によって引き起こされます

例:文字列条件は ''によって引き起こされません(dept_noは文字列です)

explain 
select * from dept_emp
where dept_no = 3;

結果のタイプはすべてです

解決策: ''、標準の書き込みSQLを追加します

5.左端のプレフィックスの原則を満たさないクエリ

解決:

インデックスの順序を調整して、index(first_name、last_name)にします。

6.インデックスフィールドにNOTNULL制約を追加することをお勧めします

単一列インデックスはnull値を格納できず、複合インデックスはすべてのnull値を格納できません。
クエリを実行するときにis null条件を使用すると、インデックスを使用できず、全表スキャン
mysqlのみが使用されます。公式の推奨事項は、フィールドは可能な限りNOTNULL

解決:

インデックスフィールドをNOTNULLに設定し、すべてのフィールドをNOT NULLに設定し、フィールドのデフォルト値を設定することもできます。

7.暗黙の変換によりインデックス障害が発生する

テーブルを作成するときは、できるだけ標準になるようにしてください。たとえば、intまたはbigintを使用します。

インデックスタイプ(一般的に使用される6):

インデックスの失敗はすべて(全表スキャン)の
カバーインデックスです:インデックスから直接クエリ結果を取得します。カバーインデックスを使用するには、インデックス列に含まれるクエリ列の選択に注意する必要があります。条件にはインデックス列または複合インデックスの先頭の列; query結果のフィールド長は可能な限り小さくなります。

1.すべて

「全表スキャン」とは、通常、SQLステートメントが最もネイティブな状態にあり、最適化の余地が大きいことを意味します。必要がない限り、このタイプのルックアップは避ける必要があります。

2.インデックス

この接続タイプは、全表スキャンの単なる別の形式ですが、スキャンの順序はインデックスの順序に従います。この種のスキャンはインデックスに基づいており、データをフェッチするためにテーブルに戻ります。すべてと比較して、両方ともテーブル全体のデータを取得し、インデックスは最初にインデックスを読み取り、テーブルに戻ってデータをランダムにフェッチする必要があります。 。

3.範囲

範囲とは、インデックススキャンの範囲を指します。インデックスのフルインデックススキャンと比較すると、範囲制限があるため、インデックスよりも優れています。範囲は理解しやすく、覚えておく必要があるのはです出现了range,则一定是基于索引的同時に、との間の明らかなことに加えて、および '>'、 '<'、およびまたははインデックス範囲スキャンでもあります。

4.参照

この接続タイプが表示される条件は次のとおりです。検索条件列はインデックスを使用し、主キーではなく、一意ではありません
実際には、インデックスは使用されますが、インデックス列の値は一意ではなく、重複することを意味します。このように、インデックスを使用して最初のデータをすばやく見つけたとしても、それを停止することはできず、目標値に近い狭い範囲のスキャンが必要になります。
ただし、その利点は、インデックスが順序付けられているため、テーブル全体をスキャンする必要がないことです。重複する値がある場合でも、非常に狭い範囲でスキャンされます。

5. ref_eq

ref_eqとrefの違いは、このタイプの検索結果セットが1つしかないことを知っているということです。どのような状況でも、結果セットは1つだけです。これは、検索に主キーまたは一意のインデックスが使用される場合です。たとえば、学生IDに従って特定の学校の学生を検索するには、検索する前に結果が1つだけである必要があることがわかっているため、初めての学生ID、クエリはすぐに停止しました。この接続タイプは、過度のスキャンを行わずに毎回正確なクエリを実行するため、検索効率が高くなります。もちろん、実際の状況に応じて列の一意性を判断する必要があります。

6. const

通常の状況では、条件付きクエリとして主キーがwhereの後に配置されている場合、mysqlオプティマイザはクエリ最適化を定数に変換できます。変換方法と変換時期については、オプティマイザーによって異なります。

おすすめ

転載: blog.csdn.net/Beyond_Nothing/article/details/114253664