クエリオプティマイザの役割はSQLクエリの実行に際し、最適なプランを検索することです。「良い」と「悪い」プランのパフォーマンス性の違いは、マグニチュードの順序(つまり、秒に対する時間、または日にち)であるため、MySQLを含む大抵のクエリオプティマイザは全ての評価可能なプランの中から最適なプランを検索します。joinクエリに対して、MySQLオプティマイザによって確認される可能なプランの数は、クエリで参照されるテーブル数と共に、急激に増加します。少ない数のテーブル(通常から7–10以下)に対して、これは問題とはなりません。 しかし、大きなクエリが提出されたとき、クエリの最適化に要する時間はサーバのパフォーマンスを低下させる主な原因となります。
フレキシブルなクエリ最適化メソッドは、最適なクエリ評価プランを、オプティマイザがどれほど徹底的に検索するかを管理します。基本的には、オプティマイザによって確認されるプランが少なければ少ないほど、クエリをコンパイルするのに要する時間も少なくてすむと考えられています。一方で、オプティマイザはいくつかのプランをスキップするため、最適プランを見逃す可能性もあります。
評価するプラン数に対するオプティマイザの動作は二つのシステム変数を通して管理されます。
optimizer_prune_level
変数はオプティマイザに、各テーブルにアクセスされた行数の見積もりに基づくプランをスキップさせます。経験上この種類の「推測」は最適プランを見過ごすことはほとんどなく、劇的にクエリをコンパイルする時間を減少させます。(optimizer_prune_level=1
)
のオプションがデフォルトなのはこのためです。ただし、オプティマイザがより適したクエリプランを見逃したと思う場合は、クエリのコンパイルにかなりの時間を要するリスクを伴いますが、このオプション(optimizer_prune_level=0
)
は停止できます。この発見的方法を使用しても、オプティマイザは、指数的なプランの数を検索します。
optimizer_search_depth
変数はオプティマイザが各不完全プランの「先」をどのくらい見通すかを示すほか、さらに拡張が必要かを評価します。optimizer_search_depth
のさらに小さい値は、マグニチュード順序あるいはクエリのコンパイルに要する時間が劇的に減少します。例えば、12,
13,
もしくはそれ以上のテーブルのクエリは、optimizer_search_depth
がクエリ内のテーブル数に近い場合、
コンパイルするのに数時間、時には数日間を容易に必要とします。同時に、3か4と等価のoptimizer_search_depth
でコンパイルされた場合、オプティマイザは同じクエリでは1分以下でコンパイル可能な場合があります。optimizer_search_depth
にとってリーズナブルな値が不明確な場合、変数を0に設定することで、オプティマイザに自動的に値を決定させることができます。