この節では WHERE
        節をプロセスする際の最適化方法を記述します。例では
        SELECT
        ステートメントを使用していますが、DELETE
        および UPDATE
        ステートメントの
        WHERE
        節にも同じ最適化が適用されます。
      
また、この節は完全なものではないため、注意が必要です。MySQL は多様な最適化を実行するため、すべてを文書化するには時間が足りませんでした。
MySQL によって実行される最適化の一部をここに紹介します
不要なかっこの削除。
((a AND b) AND c OR (((a AND b) AND (c AND d)))) -> (a AND b AND c) OR (a AND b AND c AND d)
定数の折りたたみ。
(a<b AND b=c) AND a=5 -> b>5 AND b=c AND a=5
定数条件の削除 (定数の折りたたみに必要)。
(B>=5 AND B=5) OR (B=6 AND 5=5) OR (B=7 AND 5=6) -> B=5 OR B=6
インデックスが使用する定数式が評価されるのは、1 回に限られる。
            COUNT(*)
            WHERE
            がない単一テーブルの COUNT(*)
            は、MyISAM と
            HEAP
            テーブルのテーブル情報から直接取り出される。これは、テーブル
            1 つのみで使用する場合はすべての
            NOT NULL
            式でも実行される。
          
            無効定数式の早期検出。MySQL は実行不可能な
            SELECT
            ステートメントがある場合、それを迅速に検出し、結果としてレコードを返さない。
          
            GROUP BY
            またはグループ関数
            (COUNT()、MIN())
            を使用しない場合、HAVING
            は WHERE
            とマージされる。
          
            サブ結合のそれぞれに、単純な
            WHERE
            が構造化され、サブ結合ごとに迅速に
            WHERE
            評価を取得し、可能なかぎり迅速にレコードをスキップする。
          
クエリー内のほかのすべてのテーブルの前に、まず、すべての定数テーブルが読み込まれる。定数テーブルとは次のものを指す。
空白テーブルまたは 1 行のみのテーブル。
                UNIQUE
                インデックスまたは
                PRIMARY KEY を使う
                WHERE
                節とともに使用されるテーブルで、インデックス部分のすべてが定数式とともに使用され、そのインデックス部分が
                NOT NULL
                として定義されている場合。
              
次のテーブルはすべて定数テーブルとして使用される。
SELECT * FROM t WHEREprimary_key=1; SELECT * FROM t1,t2 WHERE t1.primary_key=1 AND t2.primary_key=t1.id;
            テーブルを結合する最適な結合の組み合わせは、すべての可能性を試行してみることで発見される。ORDER
            BY および GROUP
            BY 内のすべてのカラムが 1
            つのテーブルに存在する場合、結合を行うときは第一にこのテーブルが選ばれる。
          
            ORDER BY
            節とそれと異なる GROUP
            BY
            節がある場合、あるいは、ORDER
            BY または GROUP
            BY に結合キューの第 1
            テーブルとは異なるテーブルのカラムが含まれている場合は、一時テーブルが作成される。
          
            SQL_SMALL_RESULT
            を使用する場合、MySQL
            ではメモリー内の一時テーブルが使用される。
          
オプティマイザがテーブルスキャンをしたほうが効率的と判断しないかぎり、テーブルインデックスごとにクエリーが行われ、スパンがレコードの 30% 以上である最適インデックスが使用される。しかし、現在では一定の率でインデックスかスキャンを使用するか判断されます。今バージョンのオプティマイザはより複雑で、テーブルサイズ、行数、そして I/O ブロックサイズを基準に推定します。
状況によっては、MySQL でデータファイルの参照もせずにインデックスからレコードを読み取れる場合もある。インデックスから使用されるカラムのすべてが数値型の場合、クエリーの解決にはインデックスツリーのみが使用される。
            レコードのそれぞれが出力される前に、HAVING
            節と一致しないレコードはスキップされる。
          
非常に高速なクエリーのサンプルをいくつか紹介します。
SELECT COUNT(*) FROMtbl_name; SELECT MIN(key_part1),MAX(key_part1) FROMtbl_name; SELECT MAX(key_part2) FROMtbl_nameWHEREkey_part1=constant; SELECT ... FROMtbl_nameORDER BYkey_part1,key_part2,... LIMIT 10; SELECT ... FROMtbl_nameORDER BYkey_part1DESC,key_part2DESC, ... LIMIT 10;
MySQL は次のクエリーで、インデックスツリーのみを使用して解決します (インデックスのあるカラムが数値型であると想定)。
SELECTkey_part1,key_part2FROMtbl_nameWHEREkey_part1=val; SELECT COUNT(*) FROMtbl_nameWHEREkey_part1=val1ANDkey_part2=val2; SELECTkey_part2FROMtbl_nameGROUP BYkey_part1;
次のクエリーは、ソートのパスを分けることなく、ソートしたレコードを取り出すためにインデックスを使用します。
SELECT ... FROMtbl_nameORDER BYkey_part1,key_part2,... ; SELECT ... FROMtbl_nameORDER BYkey_part1DESC,key_part2DESC, ... ;

