クエリオプティマイザの役割は SQL クエリーの実行に際し、最適なプランを検索することです。「良い」と「悪い」プランのパフォーマンス性の違いは、マグニチュードの順序 (つまり、秒に対する時間、または日にち) であるため、MySQL を含む大抵のクエリオプティマイザはすべての評価可能なプランの中から最適なプランを検索します。join クエリーに対して、MySQL オプティマイザによって確認される可能なプランの数は、クエリーで参照されるテーブル数と共に、急激に増加します。少ない数のテーブル (通常は 7 - 10 未満) に対しては、これは問題になりません。しかし、大きなクエリーが提出されたとき、クエリーの最適化に要する時間はサーバーのパフォーマンスを低下させる主な原因となります。
フレキシブルなクエリー最適化メソッドは、最適なクエリー評価プランを、オプティマイザがどれほど徹底的に検索するかを管理します。基本的には、オプティマイザによって確認されるプランが少なければ少ないほど、クエリーをコンパイルするのに要する時間も少なくてすむと考えられています。一方で、オプティマイザはいくつかのプランをスキップするため、最適プランを見逃す可能性もあります。
評価するプラン数に対するオプティマイザの動作は 2 つのシステム変数を通して管理されます。
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
に設定することで、オプティマイザに自動的に値を決定させることができます。