B ツリーおよびハッシュデータ構造を理解することは、インデックスにこれらのデータ構造を使用するさまざまなストレージエンジンで (特に B ツリーインデックスを使用するか、ハッシュインデックスを使用するかを選択できる MEMORY
ストレージエンジンの場合に)、さまざまなクエリーがどのように実行されるかを予測するのに役立つ可能性があります。
B ツリーインデックスは =
、>
、>=
、<
、<=
、または BETWEEN
演算子を使用する式で、カラム比較に使用できます。 このインデックスは、LIKE
への引数がワイルドカード文字で始まらない定数文字列の場合の LIKE
比較にも使用できます。 たとえば、次の SELECT
ステートメントはインデックスを使用します。
SELECT * FROM tbl_name WHERE key_col LIKE 'Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE 'Pat%_ck%';
最初のステートメントでは、'Patrick' <=
の行のみが考慮されます。 2 つめのステートメントでは、key_col
< 'Patricl''Pat' <=
の行のみが考慮されます。
key_col
< 'Pau'
次の SELECT
ステートメントはインデックスを使用しません。
SELECT * FROM tbl_name WHERE key_col LIKE '%Patrick%';
SELECT * FROM tbl_name WHERE key_col LIKE other_col;
最初のステートメントでは、LIKE
値はワイルドカード文字で始まります。 2 つめのステートメントでは、LIKE
値は定数ではありません。
... LIKE '%
を使用し、string
%'string
が 3 文字より長い場合、MySQL は Turbo Boyer-Moore アルゴリズムを使用して、文字列のパターンを初期化してから、このパターンを使用して検索をより迅速に実行します。
を使用した検索では、col_name
IS NULLcol_name
にインデックスが設定されている場合にインデックスが使用されます。
WHERE
句内のすべての AND
レベルにまたがっていないインデックスは、クエリーの最適化に使用されません。 言い換えると、インデックスの使用を可能にするには、インデックスのプリフィクスがすべての AND
グループで使用されている必要があります。
次の WHERE
句ではインデックスが使用されます。
... WHERE index_part1=1 AND index_part2=2 AND other_column=3
/* index = 1 OR index = 2 */
... WHERE index=1 OR A=10 AND index=2
/* optimized like "index_part1='hello'" */
... WHERE index_part1='hello' AND index_part3=5
/* Can use index on index1 but not on index2 or index3 */
... WHERE index1=1 AND index2=2 OR index1=3 AND index3=3;
これらの WHERE
句ではインデックスが使用されません。
/* index_part1 is not used */
... WHERE index_part2=1 AND index_part3=2
/* Index is not used in both parts of the WHERE clause */
... WHERE index=1 OR A=10
/* No index spans all rows */
... WHERE index_part1=1 OR index_part2=10
MySQL ではインデックスが使用できる場合でも使用しないことがあります。 これが発生する 1 つの状況は、オプティマイザが、インデックスを使用することによって MySQL がテーブルの大部分の行にアクセスする必要があると推定した場合です。 (この場合、必要なシークが少ないため、テーブルスキャンの方がはるかに高速になる可能性があります。) ただし、そのようなクエリーで、行の一部のみを取得する LIMIT
を使用している場合、結果で返す少数の行をはるかにすばやく見つけることができるため、MySQL はとにかくインデックスを使用します。
ハッシュインデックスは先述したものといくらか異なる特性を持ちます。
それらは、
=
または<=>
演算子を使用する等価比較にのみ使用されます (ただしきわめて高速です)。 それらは、値の範囲を見つける<
などの比較演算子には使用されません。 この種類の単一値ルックアップに依存するシステムは、「キー値ストア」として知られています。そのようなアプリケーションで MySQL を使用するには、可能なかぎりハッシュインデックスを使用します。オプティマイザはハッシュインデックスを使用して、
ORDER BY
操作を高速化することはできません。 (この種類のインデックスは順番に次のエントリを検索するために使用できません。)MySQL は 2 つの値の間におよそどのくらいの行数があるかを判断できません (これは範囲オプティマイザによって使用するインデックスを特定するために使用されます)。 これは、
MyISAM
またはInnoDB
テーブルをハッシュインデックス設定されたMEMORY
テーブルに変更した場合に、一部のクエリーに影響することがあります。行の検索にはキー全体のみを使用できます。 (B ツリーインデックスでは、キーの任意の左端のプリフィクスを使用して行を検索できます。)