へっぽこITエンジニア@名古屋のブログ

Follow me on GitHub

Oracle12cの適応計画の外し方

Oracle12cでは適応計画というのがあり、 実際に動作した実行計画から変えて最適なのを探すという機能があります。

しかし、SQLが大きくなって複雑になると逆効果の時があります。 早くなったり遅くなったりと。

そんなときのために、暫定的な対策としてヒント句を利用する方法があります。
今回はそれを紹介します

ヒント句を利用してOptimizerを古いのにする

対処方法は簡単です。 ヒント句でOPTIMIZER_FEATURES_ENABLEを利用して11gに戻すだけです。

select /*+ OPTIMIZER_FEATURES_ENABLE('11.2.0.4') */

しかしながら、11gではできなかった書き方で書いてると怒られることがあります。

たとえば、外部結合で福問い合わせをしている場合です。

以下のSQLでは、最終ログイン日のデータをleft joinしています。

left join CUSTOMER_LOGIN CUST
  on CUST.LOGIN_DATE = (select max(LOGIN_DATE)
    from CUSTOMER_LOGIN TMP
    where CUST.ID = TMP.ID)

これだと、
ORA-01799: 列は副問合せに対して外部結合されません。
となってしまいます。

そこで、not existsを利用して以下のように書きます。

left join CUSTOMER_LOGIN CUST
  not exists (select '1'
    from CUSTOMER_LOGIN TMP
    where CUST.ID = TMP.ID
      and CUST.LOGIN_DATE < TMP.LOGIN_DATE)

<>を間違えそうで怖い・・・

ただ、11gにもどすと、データに偏りがあった時に誤った実行計画が作られて 遅くなった場合に改善されなかったりする気がするので、 できるだけ適応計画を利用したほうがよい気がします。

まとめ

oracle12cからの適応計画ですが、SQLが複雑すぎる場合、逆効果の時があるようです。 その際は、ヒント句を利用してOptimizerを11gにすることで適応計画を外すことができます。

その際に、11gで利用できない書き方をしているとエラーになるので修正が必要です。

あくまで最終手段で、SQLを簡潔にするなどしてできるだけ対処するほうがよいとは思います。

作成日:2023-04-23  更新日:2023-04-23