[Oracle] 任意のヒントを指定したストアドアウトラインの作成

2013年1月11日

 ストアドアウトラインによる実行計画の固定のメモ。一応 10g までが対象。(11g からは SPM)

 例題として、現在、INDEX UNIQUE SCAN を行う以下の問い合わせがあったとします。

SQL> select * from emp where empno=999;

実行計画
---------------------------------------------------
Plan hash value: *********

----------------------------------------------
| Id  | Operation                   | Name   |
----------------------------------------------
|   0 | SELECT STATEMENT            |        |
|   1 |  TABLE ACCESS BY INDEX ROWID| EMP    |
|*  2 |   INDEX UNIQUE SCAN         | PK_EMP |
----------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - access("EMPNO"=999)

 この問い合わせの実行計画を INDEX UNIQUE SCAN ではなく、TABLE ACCESS FULL となるように変更したいとします。

 手順は以下。

  1. ヒントなしのアウトラインを作成します。
    -- ヒントなしのアウトラインを作成
    create or replace outline NO_HINT
    ON
    select * from emp where empno=999;
    
  2. TABLE ACCESS FULLとなるようヒントを指定した時のアウトラインを作成します。
    -- ヒント指定のアウトラインを作成
    create or replace outline SET_HINT
    ON
    select /*+ full(emp) */ * from emp where empno=999;
    
  3. 双方のヒントを入れ替えます。(*1)
    -- ヒントの入れ替え
    update outln.ol$hints
       set ol_name = decode(ol_name,'SET_HINT','NO_HINT','NO_HINT','SET_HINT')
     where ol_name in ('SET_HINT','NO_HINT')
    ;
    commit;
    
  4. ストアドアウトラインを有効にします。(*2)
    alter system set USE_STORED_OUTLINES=TRUE;
    

 このようにすると、ヒント句なしで問い合わせを実行しても、TABLE ACCESS FULL を選択するようになります。(*3)
 (実行計画レポートの note のところに ストアドアウトラインを使用しているという表示が出ます。)

SQL> select * from emp where empno=999;

実行計画
--------------------------------------------------
Plan hash value: *********

----------------------------------
| Id  | Operation         | Name | 
----------------------------------
|   0 | SELECT STATEMENT  |      | 
|*  1 |  TABLE ACCESS FULL| EMP  |
----------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   1 - filter("EMPNO"=999)

Note
-----
   - outline "NO_HINT" used for this statement

  1.  HINT の内容がどのようなものか確認したい場合は、たとえば以下。

    col OL_NAME for A10
    col HINT_TEXT for A60
    
    select
        OL_NAME, STAGE#, HINT#, HINT_TEXT
    from
        OUTLN.OL$HINTS
    where
        OL_NAME='NO_HINT'
    order by
        STAGE#, HINT#;
    
  2.  ストアドアウトラインに登録されている SQL 文を確認したい場合は、たとえば以下。

    select
        NAME, SQL_TEXT
    from
        DBA_OUTLINES;
    
  3.  11gR1 (11.1.0.6 for Win x86) では動作しませんでした。(アウトラインが無効になっている感じ)
     10gR2 (10.2.0.1 for Win x86) / 11gR2 (11.2.0.1 for CentOS x86) では期待通り動作。
     # いずれも OS は日本語、DB の文字セットも日本語(JA16SJIS または JA16SJISTILDE)で確認。






カテゴリー: Oracle, データベース

Follow comments via the RSS Feed | Leave a comment | Trackback URL

コメントを投稿する

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


«   »
 
Powered by Wordpress and MySQL. Theme by Shlomi Noach, openark.org