explain plan、set autotraceの実行計画は実際とは異なる実行計画が表示される場合がある

掲題の通り、explain planやset autotraceで表示される実行計画は実際に実行したときの実行計画ではない場合があります。 異なる実行計画になる要因は以下のようなものがあります。

  • バインド変数を使用したSQL文でバインドピーク機能を有効化している(デフォルト有効)
  • クライアント側で設定するバインド変数の型がデータベース上の表の列型と一致していない
  • 11g以降の最適化機能(カーソル共有や適応計画等)が働いている

異なる実行計画が表示される理由

バインド変数を用いたSQLであってもexplainコマンドはバインド変数の型、値を設定せずとも実行することができます。 つまり、バインドピーク機能やカーソル共有機能が有効であってもバインド変数の中身は一切評価せず、バインド変数の型も適切である前提で実行計画を立てることになる為実行時の実行計画と異なる実行計画になるケースが発生します。 適応計画に関しては実際に実行した時点でカーディナリティ見積もりの乖離を検知することで発動する機能のため実際にデータにアクセスしないexplainだと異なる実行計画になる場合があります。

正確な実行計画を確認するには

正確な実行計画を確認するために実際にSQLを実行した上で、以下のような実際に実行されたSQLカーソルに紐づく実行計画を確認する必要があります。 方法としては以下のようなものがあります。

  • dbms_xplan.display_cursor。なお、dbms_xplan.display_cursor(null,null)を引数指定すると直前に実行したSQLの実行計画を表示することができる
  • V$SQL_PLANをSQL_IDを条件に検索。SQL_IDはV$SQLにSQL_FULLTEXT(SQL文)やLAST_ACTIVE_TIME(SQLが最後に稼働していた時間)等から検索すると良い
★ORACLE案件承ります