WHERE
テーブルの統計が正確である場合、句にハードコーディングされた要素が 1000 個しかない場合に、オプティマイザーが主キー インデックスを使用する代わりにテーブル スキャンを実行することを選択する可能性はほとんどありません。最良のアプローチは、オブジェクトの正確な統計を収集 (または設定) することです。これにより、誤った統計を回避するために多くの体操を行うのではなく、自動的に良いことが起こるはずです。
オプティマイザが主キー インデックスを使用するよりもテーブル スキャンの方が効率的であると信じるほど統計が不正確であると仮定した場合DYNAMIC_SAMPLING
、オプティマイザがより正確に収集するように強制するヒントを追加できる可能性があります。ステートメントを最適化する前の統計、またはCARDINALITY
オプティマイザのデフォルトのカーディナリティ推定をオーバーライドするためのヒント。どちらも、使用可能なインデックスについて何も知る必要はありません。テーブルのエイリアス (またはエイリアスがない場合は名前) を知る必要があるだけです。 DYNAMIC_SAMPLING
より安全で堅牢なアプローチになりますが、解析ステップに時間がかかります。
句内に可変数のハードコーディングされたパラメーターを使用して SQL ステートメントを構築している場合IN
、共有プールを共有不可能な SQL であふれさせ、データベースに 1 つのコストを強制的に費やすことで、パフォーマンスの問題を引き起こす可能性があります。各バリアントを個別に解析するのに多くの時間がかかります。一度解析できる単一の共有可能な SQL ステートメントを作成すると、はるかに効率的になります。IN
句の値がどこから来ているかによって、次のようになります
SELECT *
FROM table_name
WHERE primary_key IN (SELECT primary_key
FROM global_temporary_table);
また
SELECT *
FROM table_name
WHERE primary_key IN (SELECT primary_key
FROM TABLE( nested_table ));
また
SELECT *
FROM table_name
WHERE primary_key IN (SELECT primary_key
FROM some_other_source);
単一の共有可能な SQL ステートメントに落ち着いた場合、ステートメントを絶えず再解析するコストを回避することに加えて、SQL ステートメントの変更を伴わない特定の計画を強制するための多くのオプションがあります。Oracle のバージョンが異なれば、プランの安定性のためのオプションも異なります。リリースに応じて、その他のテクノロジーの中でも、アウトラインの保存、SQL プランの管理、およびSQL プロファイルがあります。これらを使用して、特定の SQL ステートメントに対して特定の計画を強制することができます。ただし、再解析が必要な新しい SQL ステートメントを生成し続けると、これらのテクノロジを使用することが非常に難しくなります。