インデックスの作成と設計の原則

1. 指数の分類

機能ロジックの観点から、通常のインデックス、一意のインデックス、主キー インデックス、および全文インデックスに分類されます。

  • 通常インデックス (NORMAL) : クエリ効率を向上させるためだけの制限のないインデックス。
  • 一意のインデックス (UNIQUE) : インデックスの値は一意である必要がありますが、NULL 値も許可され、テーブルには複数の一意のインデックスを持つことができます。
  • 主キー インデックス: 空でない制約を追加する特別な一意のインデックス。テーブルには最大 1 つの主キー インデックスがあります。
  • 全文インデックス (FULLTEXT) : 単語分割テクノロジとその他のアルゴリズムを使用して、キーワードの頻度と重要性を分析し、大規模なデータ セットに適していますフルテキスト インデックスは、CHAR、VARCHAR、または TEXT タイプのフィールドとそのシリーズ タイプにのみ作成できます大量のデータを含む文字列タイプのフィールドをクエリする場合、フルテキスト インデックスを使用するとクエリ速度が向上しますたとえば、テーブル Student のフィールド情報のタイプは TEXT であり、このフィールドには多くのテキスト情報が含まれています。フィールド情報に全文インデックスを作成すると、フィールド情報のクエリの速度が向上します。ビッグ データ時代の到来により、リレーショナル データベースは全文インデックス作成の需要に対応できなくなり、Solr や ElasticSearch などの特殊な検索エンジンに徐々に置き換えられています

物理的な実装に従って、クラスター化インデックスと非クラスター化インデックスに分けられます。

  • クラスター化インデックス: 主キーに基づいて構築されるインデックスはデータ格納方法であり、テーブルのデータ行はインデックス ツリーのリーフ ページに格納されます。
  • 非クラスター化インデックス: 非主キーに基づいて構築されたインデックス。完全なレコードは保存されず、インデックス列によって並べ替えられます。

使用するフィールドの数に応じて、単一列インデックスと結合インデックスに分けられます。

  • シングルトン インデックス: テーブル内の単一フィールドにインデックスを作成します。単一列のインデックスは、このフィールドに基づいてのみインデックス付けされます。単一列インデックスは、通常のインデックス、一意のインデックス、またはフルテキスト インデックスのいずれかになります。インデックスが 1 つのフィールドのみに対応していることを確認してください。テーブルには複数の単一列インデックスを含めることができます。
  • 複数列インデックス: テーブル内の複数のフィールドの組み合わせにインデックスを作成します。インデックスは、作成時に複数の対応するフィールドを指します。これらのフィールドを通じてクエリを実行できますが、クエリ条件で使用されるのはこれらのフィールドの最初のフィールドのみです。たとえば、テーブルのフィールド ID、名前、性別に複数列インデックス idx_id_name_gender を作成します。このインデックスは、フィールド ID がクエリ条件で使用される場合にのみ使用されます。結合インデックスを使用する場合は、左端のプレフィックス セットに従います。

ストレージ エンジンが異なれば、サポートされるインデックス タイプも異なります。

  • InnoDB: B+ ツリー、フルテキストおよびその他のインデックスをサポートしますが、ハッシュ インデックスはサポートしません
  • MyISAM: B+ ツリー、フルテキストおよびその他のインデックスをサポートしますが、ハッシュ インデックスはサポートしません
  • メモリ: B+ ツリー、ハッシュ、その他のインデックスをサポートしますが、フルテキスト インデックスはサポートしません

2. インデックス設計の原則

インデックスの作成に適しています

1. WHERE 条件としてよく使用されるフィールド

フィールドが SELECT、UPDATE、または DELETE ステートメントの WHERE 条件で頻繁に使用される場合は、このフィールドのインデックスを作成する必要があります。特にデータ量が多い場合、共通インデックスを作成するとデータクエリの効率が大幅に向上します。

2. 頻繁に使用される GROUP BY 列と ORDER BY 列

インデックスを使用すると、データを特定の順序で保存または取得できるため、GROUP BY を使用してデータをグループ化する場合、または ORDER BY を使用してデータを並べ替える場合は、グループ化または並べ替えられたフィールドにインデックスを付ける必要があります。インデックスを作成する必要がある列が複数ある場合は、これらの列に複合インデックスを作成できます。

  • インデックスを作成する必要がある列が 1 つだけの場合 (たとえば、GROUP BY から Student_id まで)
SELECT student_id, COUNT(*) AS num 
FROM student_info 
GROUP BY student_id

Student_id にインデックスを追加して、クエリ速度を向上させることができます。同様に、ORDER BYの場合は、対応するフィールドにインデックスを追加することもできます。

  • たとえば、インデックスを作成する必要がある列が複数ある場合、GROUP BY と ORDER BY の両方が存在します。
SELECT student_id, COUNT(*) AS num FROM student_info 
GROUP BY student_id 
ORDER BY create_time DESC 

Student_id と create_time にそれぞれインデックスを作成すると、実際には Student_id のインデックスのみが使用され、実行速度が遅くなることがわかります。複数の単一列インデックスは複数条件クエリでのみ有効となるため (MSOL は最も制限的なインデックスをインデックスとして選択します)、複数条件結合クエリを実行する場合は結合インデックスを作成することをお勧めします。

通常はSQLの実行順序に従ってジョイントインデックスを作成する必要がありますが、group byが先に実行されるため、(create_time,student_id)ではなく(student_id,create_time)のジョイントインデックスを作成する必要があります。ここで、(create_time,student_id) 順次結合インデックスと Student_id 単一列インデックスが共存する場合でも、group by が最初に実行されるため、student_id 単一列インデックスが引き続き使用されることに注意してください。

3. 頻繁に DISTINCT 列が使用される

場合によっては、特定のフィールドの重複を排除する必要がある場合があります。DISTINCT を使用して、このフィールドにインデックスを作成すると、クエリの効率も向上します。

4. 複数表JOIN接続時のインデクス作成時の注意事項

  1. まず第一に、接続テーブルの数はできる限り 3 を超えないようにしてください。これは、テーブルを追加するたびにネストされたループを追加することに相当し、増加が非常に速くなり、クエリの効率に重大な影響を与えるためです。
  2. 次に、WHERE 条件のインデックスを作成します。これは、WHERE がデータ条件のフィルターであるためです。データの量が非常に大きい場合、WHERE 条件を使用しないフィルタリングは非常に危険です。
  3. 最後に、結合に使用されるフィールドにインデックスを作成します。また、このフィールドの型は複数のテーブルで一致している必要があり、関数変換を使用するとインデックスが無効になります。

5. 列のデータ型はできるだけ小さくする必要があります。

ここで言う型のサイズとは、型によって表されるデータ範囲のサイズを指します。

  • データ型が小さいほど、クエリ時の比較操作が高速になります。
  • データ型が小さいほど、インデックスが占有するストレージ領域が少なくなり、より多くのレコードを 1 つのデータ ページに配置できるため、ディスク I/O によるパフォーマンスの損失が軽減されます。つまり、より多くのデータ ページをメモリにキャッシュできることになります。読み取りと書き込みの効率を高速化します

この提案は、主キー値がクラスター化インデックスに格納されるだけでなく、レコードの主キー値も他のすべてのセカンダリ インデックス ノードにも格納されるため、 table の主キーにさらに当てはまりますキーはより小さいデータ型を使用します。これは、より多くのストレージスペースとより効率的な I/O を節約することを意味します。

6. 文字列プレフィックスを使用してインデックスを作成する

文字列が非常に長いと仮定すると、文字列を保存すると多くのストレージ スペースが必要になります。この文字列列にインデックスを付ける必要がある場合、次の 2 つの問題が発生します。

  • 文字列比較が遅い
  • 多くの保管スペースを占有します

フィールドの前の部分をインターセプトすることでインデックスを作成できます。これはプレフィックス インデックスと呼ばれます。このようにして、レコードの検索時にレコードの位置を正確に特定することはできませんが、対応するプレフィックスの位置を特定し、レコードの主キー値に基づいて完全な文字列値をテーブルに返すことができます。同じプレフィックスを持つレコード。スペースを節約するだけでなく、文字列の比較時間も短縮されます。

さまざまな長さのハッシュの傍受度を計算します (選択的)

たとえば、傍受されたアドレス長のハッシュ次数を検出します。

select count(distinct left(列名,索引长度)) / count(*) from 表;

もちろん、1 に近いほど効果が高く、ハッシュ化の度合いが高いことを示します。

7. 識別性の高い(ハッシュ性が高い)カラムはインデックスとして適しています

列のカーディナリティは、列内の固有のデータの数を指します。たとえば、列には値 2、5、8、2、5、8、2、5、8 が含まれています。レコードは 9 つありますが、列のカーディナリティは 3 です。つまり、レコード行数が一定の場合、列のカーディナリティが大きいほど、その列内の値はより分散し、列のカーディナリティが小さいほど、その列内の値はより集中します。コラムは。

この列のカーディナリティ インデックスは非常に重要であり、インデックスを効果的に利用できるかどうかに直接影響します。インデックスの値は迅速に検索できるようにするためのものであるため、検索する必要があるデータが大量にある場合、インデックスは通常の性別フィールドなどの使用価値を失います。

数式を使用して区別度を計算できます。1 に近いほど優れています。一般に、33% を超えると比較的効率的なインデックスとみなされ、一意のフィールドはインデックスの作成に適しています。

select count(distinct 列名)/count(*) from 表名

8.最も頻繁に使用される列を結合インデックスの左側に配置します。

これにより、作成するインデックスの数も少なくなります。同時に、「左端の接頭辞の原則」により、結合インデックスの使用量を増やすことができます。

9.複数のフィールドにインデックスを付ける必要がある場合は、単一値インデックスよりも結合インデックスの方が適しています。

インデックスの作成には適していません

1. データ量が少ないテーブルにはインデックスを使用しないことをお勧めします

テーブルのレコードが少なすぎる場合 (1,000 未満など)、インデックスを作成する必要はありません。テーブルのレコードが少なすぎるため、インデックスを作成するかどうかはクエリの効率にほとんど影響しません。クエリはインデックスを走査するよりも時間がかからず、インデックスによる最適化効果が得られない可能性があるとも言われています。

2. 頻繁に更新されるテーブルに大量のインデックスを作成しないようにする

  • データが更新されるとインデックスも更新する必要があるため、頻繁に更新されるフィールドにはインデックスを作成する必要はありませんが、インデックスが多すぎると更新中にサーバーに負荷がかかり、効率が低下します。
  • 頻繁に更新されるテーブルにあまりにも多くのインデックスを作成しないようにし、インデックス内の列をできるだけ少なくします。このときクエリ速度は向上しますが、テーブルの更新速度も低下します。

3. 大量の重複データを含む列にインデックスを作成しないでください。

条件式でよく使用されるさまざまな値を持つ列にインデックスを作成しますが、フィールド内に大量の重複データがある場合は、インデックスを作成する必要はありません。たとえば、student テーブルの性別フィールドには男性と女性の 2 つの値しかないため、インデックスを作成する必要はありません。インデックスを作成すると、クエリ効率が向上しないだけでなく、データ更新速度が大幅に低下します。

3. インデックスの数を制限する

実際の作業ではバランスにも気を配る必要があり、インデックスは多ければ多いほど良いです。各テーブルのインデックスの数を制限する必要があるため、1 つのテーブルに 6 つ以下のインデックスを設定するのが最善です理由:

  1. 各インデックスにはディスク領域が必要であり、インデックスが増えるほど、より多くのディスク領域が必要になります。
  2. インデックスは、INSERT、DELETE、UPDATE などのステートメントのパフォーマンスに影響します。これは、テーブル内のデータが変更されると、インデックスも調整および更新され、負担がかかるためです。
  3. オプティマイザーがクエリを最適化する方法を選択するとき、統合された情報に基づいて利用可能な各インデックスを評価して、最適な実行プランを生成します。クエリに同時に使用できるインデックスが多数ある場合、MySQL オプティマイザーは増加します。クエリのパフォーマンスを低下させる実行プラン時間が生成されます。

おすすめ

転載: blog.csdn.net/qq_62767608/article/details/132018029