MySQL 8.0 リファレンスマニュアル


MySQL 8.0 リファレンスマニュアル  /  ...  /  MySQL のインデックスの使用の仕組み

8.3.1 MySQL のインデックスの使用の仕組み

インデックスは特定のカラム値のある行をすばやく見つけるために使用されます。 インデックスがないと、MySQL は関連する行を見つけるために、先頭行から始めてテーブル全体を読み取る必要があります。 テーブルが大きいほど、このコストが大きくなります。 テーブルに問題のカラムのインデックスが含まれている場合、MySQL はすべてのデータを調べる必要なく、データファイルの途中のシークする位置をすばやく特定できます。 これはすべての行を順次読み取るよりはるかに高速です。

ほとんどの MySQL インデックス (PRIMARY KEYUNIQUEINDEX、および FULLTEXT) は B ツリーに格納されます。 例外: 空間データ型のインデックスは R ツリーを使用します。MEMORY テーブルはハッシュインデックスもサポートします。InnoDBFULLTEXT インデックスの逆のリストを使用します。

一般に、インデックスは次の説明に示すように使われます。 ハッシュインデックス (MEMORY テーブルで使用されているような) に固有の特性については、セクション8.3.9「B ツリーインデックスとハッシュインデックスの比較」で説明しています。

MySQL はこれらの操作にインデックスを使用します。

  • WHERE 句に一致する行をすばやく見つけるため。

  • 行を考慮に入れないようにするため。 複数のインデックスから選択する場合、MySQL は通常最小数の行を見つけるインデックス (もっとも選択的なインデックス) を使用します。

  • テーブルにマルチカラムインデックスがある場合、オプティマイザは、インデックスの左端のプリフィクスを使用して行をルックアップできます。 たとえば、(col1, col2, col3) に 3 カラムのインデックスがある場合、(col1)(col1, col2)、および (col1, col2, col3) に対して、インデックス検索機能を使用できます。 詳細については、セクション8.3.6「マルチカラムインデックス」を参照してください。

  • 結合の実行時に、ほかのテーブルから行を取得するため。 カラムが同じ型とサイズで宣言されていると、MySQL はカラムのインデックスをより効率的に使用できます。 このコンテキストでは、VARCHARCHAR は同じサイズで宣言されていれば同じとみなされます。 たとえば、VARCHAR(10)CHAR(10) は同じサイズですが、VARCHAR(10)CHAR(15) は異なります。

    非バイナリ文字列カラム間での比較の場合、両方のカラムで同じ文字セットを使用しているべきです。 たとえば、utf8 カラムと latin1 カラムの比較はインデックスの使用の可能性を否定します。

    異種のカラムの比較 (文字列カラムを時間または数値カラムと比較するなど) では、値を変換せずに直接比較できない場合、インデックスの使用が妨げられることがあります。 数値カラム内の 1 などの特定の値の場合、'1'' 1''00001'、または '01.e1' などの文字列カラム内の任意の数の値と等しくなる可能性があります。 これは、文字列カラムのインデックスの使用を除外します。

  • 特定のインデックス設定されたカラム key_col に対して、MIN() あるいは MAX() 値を見つけるため。 これはインデックス内の key_col より前に発生するすべてのキーパートで、WHERE key_part_N = constant が使用されているかどうかをチェックするプリプロセッサによって最適化されます。 この場合、MySQL は各 MIN() または MAX() 式に対して単一キールックアップを行い、それを定数で置き換えます。 すべての式が定数で置き換えられた場合、クエリーは同時に返されます。 例:

    SELECT MIN(key_part2),MAX(key_part2)
      FROM tbl_name WHERE key_part1=10;
  • 使用可能なインデックスの左端のプリフィクスに対してソートまたはグループ化が行われている場合 (たとえば、ORDER BY key_part1, key_part2) に、テーブルをソートまたはグループ化するため。 すべてのキーパートのあとに DESC が付けられている場合、キーは逆の順序で読み取られます。 (または、インデックスが降順の場合、キーは順方向に読み取られます。) セクション8.2.1.16「ORDER BY の最適化」セクション8.2.1.17「GROUP BY の最適化」、およびセクション8.3.13「降順インデックス」を参照してください。

  • 場合によって、データ行を参照しないで値を取得するように、クエリーを最適化できます。 (クエリーの必要なすべての結果を提供するインデックスは、カバーするインデックスと呼ばれます。) クエリーがテーブルから特定のインデックスに含まれるカラムのみを使用している場合、きわめて高速に、選択した値をインデックスツリーから取得できます。

    SELECT key_part3 FROM tbl_name
      WHERE key_part1=1

小さなテーブルまたは、レポートクエリーが行の大半またはすべてを処理する大きなテーブルに対するクエリーでは、インデックスはあまり重要ではありません。 クエリーで行の大半にアクセスする必要がある場合は、順次読み取る方が、インデックスを処理するより高速です。 クエリーですべての行が必要でない場合でも、順次読み取りは、ディスクシークを最小にします。 詳細は、セクション8.2.1.23「全テーブルスキャンの回避」 を参照してください。


関連キーワード:  インデックス, テーブル, カラム, InnoDB, クエリー, col, key, 結合, ステートメント, キー