インデックスは特定のカラム値のある行をすばやく見つけるために使用されます。 インデックスがないと、MySQL は関連する行を見つけるために、先頭行から始めてテーブル全体を読み取る必要があります。 テーブルが大きいほど、このコストが大きくなります。 テーブルに問題のカラムのインデックスが含まれている場合、MySQL はすべてのデータを調べる必要なく、データファイルの途中のシークする位置をすばやく特定できます。 これはすべての行を順次読み取るよりはるかに高速です。
ほとんどの MySQL インデックス (PRIMARY KEY
、UNIQUE
、INDEX
、および FULLTEXT
) は B ツリーに格納されます。 例外: 空間データ型のインデックスは R ツリーを使用します。MEMORY
テーブルはハッシュインデックスもサポートします。InnoDB
は FULLTEXT
インデックスの逆のリストを使用します。
一般に、インデックスは次の説明に示すように使われます。 ハッシュインデックス (MEMORY
テーブルで使用されているような) に固有の特性については、セクション8.3.9「B ツリーインデックスとハッシュインデックスの比較」で説明しています。
MySQL はこれらの操作にインデックスを使用します。
WHERE
句に一致する行をすばやく見つけるため。行を考慮に入れないようにするため。 複数のインデックスから選択する場合、MySQL は通常最小数の行を見つけるインデックス (もっとも選択的なインデックス) を使用します。
テーブルにマルチカラムインデックスがある場合、オプティマイザは、インデックスの左端のプリフィクスを使用して行をルックアップできます。 たとえば、
(col1, col2, col3)
に 3 カラムのインデックスがある場合、(col1)
、(col1, col2)
、および(col1, col2, col3)
に対して、インデックス検索機能を使用できます。 詳細については、セクション8.3.6「マルチカラムインデックス」を参照してください。-
結合の実行時に、ほかのテーブルから行を取得するため。 カラムが同じ型とサイズで宣言されていると、MySQL はカラムのインデックスをより効率的に使用できます。 このコンテキストでは、
VARCHAR
とCHAR
は同じサイズで宣言されていれば同じとみなされます。 たとえば、VARCHAR(10)
とCHAR(10)
は同じサイズですが、VARCHAR(10)
とCHAR(15)
は異なります。非バイナリ文字列カラム間での比較の場合、両方のカラムで同じ文字セットを使用しているべきです。 たとえば、
utf8
カラムとlatin1
カラムの比較はインデックスの使用の可能性を否定します。異種のカラムの比較 (文字列カラムを時間または数値カラムと比較するなど) では、値を変換せずに直接比較できない場合、インデックスの使用が妨げられることがあります。 数値カラム内の
1
などの特定の値の場合、'1'
、' 1'
、'00001'
、または'01.e1'
などの文字列カラム内の任意の数の値と等しくなる可能性があります。 これは、文字列カラムのインデックスの使用を除外します。 -
特定のインデックス設定されたカラム
key_col
に対して、MIN()
あるいはMAX()
値を見つけるため。 これはインデックス内のkey_col
より前に発生するすべてのキーパートで、WHERE
が使用されているかどうかをチェックするプリプロセッサによって最適化されます。 この場合、MySQL は各key_part_N
=constant
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「全テーブルスキャンの回避」 を参照してください。