1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Oracle Database Standard Edition SQLプランベースラインによる実行計画の固定化

1
Last updated at Posted at 2026-08-02

Oracle Database Standard Edition(SE2)はSQL文ごとに許可されるSQLプランベースラインは1つのみであり、以下の記事の通り、実行計画の固定化はできない。
SQLプランベースラインによる実行計画の固定化
本記事はストアドアウトライン経由で実行計画の固定化を行う。

下記SQL文を実行する。

select * from SH.CUSTOMERS where cust_id < 13894;

実行計画を確認する。

select sql_id,child_number,address,hash_value,plan_hash_value, sql_text from v$sql where sql_text like '%cust_id < 13894%' and sql_text not like '%v$sql%';

image.png

select * from table(DBMS_XPLAN.DISPLAY_CURSOR('cbnkw688amax5',0));

image.png
PRIVATE OUTLINEを作成する。

CREATE PRIVATE OUTLINE CUSTOMERS_SELECT
ON select * from SH.CUSTOMERS where cust_id < 13894;

indexを利用するPRIVATE OUTLINEを作成する。

CREATE PRIVATE OUTLINE CUSTOMERS_SELECT_USE_INDEX
ON select /*+ index(CUSTOMERS CUSTOMERS_PK) */ * from SH.CUSTOMERS where cust_id < 13894;

作成したPRIVATE OUTLINEを確認する。

--OL$はグローバル一時テーブルSYSTEM.OL$のパブリックシノニム
select OL_NAME,SQL_TEXT,CATEGORY,HINTCOUNT from OL$;

image.png

--OL$HINTSはグローバル一時テーブルSYSTEM.OL$HINTSのパブリックシノニム
select OL_NAME,HINT#,CATEGORY,HINT_TYPE,HINT_TEXT from OL$HINTS;

image.png
hint句なしのSQL文のOUTLINEをhint句ありのSQL文のOUTLINEを入れ替える。

UPDATE ol$
SET
    hintcount = (
        SELECT
            hintcount
        FROM
            ol$
        WHERE
            ol_name = 'CUSTOMERS_SELECT_USE_INDEX'
    )
WHERE
    ol_name = 'CUSTOMERS_SELECT';
    
DELETE ol$hints
WHERE
    ol_name = 'CUSTOMERS_SELECT';

UPDATE ol$hints
SET
    ol_name = 'CUSTOMERS_SELECT'
WHERE
    ol_name = 'CUSTOMERS_SELECT_USE_INDEX';

DELETE FROM ol$
WHERE
    ol_name = 'CUSTOMERS_SELECT_USE_INDEX';

編集結果を確認する。

--OL$はグローバル一時テーブルSYSTEM.OL$のパブリックシノニム
select OL_NAME,SQL_TEXT,CATEGORY,HINTCOUNT from OL$;

image.png

--OL$HINTSはグローバル一時テーブルSYSTEM.OL$HINTSのパブリックシノニム
select OL_NAME,HINT#,CATEGORY,HINT_TYPE,HINT_TEXT from OL$HINTS;

image.png
PUBLIC OUTLINEを作成する。

CREATE PUBLIC OUTLINE PUBLIC_CUSTOMERS_SELECT FROM PRIVATE CUSTOMERS_SELECT;

PUBLIC OUTLINEが作成された。

select * from dba_outlines;

image.png

select * from dba_outline_hints;

image.png
SQL文を実行し、ストアドアウトラインによる実行計画が固定化され、indexが利用されることを確認する。

ALTER SESSION SET use_stored_outlines = true;
select * from SH.CUSTOMERS where cust_id < 13894;
select sql_id,child_number,address,hash_value,plan_hash_value, sql_text from v$sql where sql_text like '%cust_id < 13894%' and sql_text not like '%v$sql%';

image.png
最新の実行計画を確認する。

select * from table(DBMS_XPLAN.DISPLAY_CURSOR('cbnkw688amax5',1));

image.png
ストアドアウトラインをSQLプランベースラインに移行する。

DECLARE
    ret CLOB;
BEGIN
    ret := dbms_spm.migrate_stored_outline(attribute_name => 'outline_name', attribute_value => 'PUBLIC_CUSTOMERS_SELECT');
    dbms_output.put_line(ret);
END;
/

image.png
PUBLIC OUTLINEが「MIGRATED」になっている。

select * from dba_outlines;

image.png
移行されたSQLプランベースラインを確認する

select signature,sql_handle, sql_text,plan_name,created,last_modified,enabled,accepted,fixed from dba_sql_plan_baselines;

image.png
移行済のPUBLIC OUTLINEを削除する。

DECLARE
    ret PLS_INTEGER;
BEGIN
    ret := DBMS_SPM.DROP_MIGRATED_STORED_OUTLINE;
END;
/

最後に、SQL文を実行し、SQL計画ベースラインによる実行計画が固定化され、indexが利用されることを確認する。

select * from SH.CUSTOMERS where cust_id < 13894;
select sql_id,child_number,hash_value,plan_hash_value, sql_text from v$sql where sql_text like '%cust_id < 13894%' and sql_text not like '%v$sql%';

image.png
最新の実行計画を確認する。

select * from table(DBMS_XPLAN.DISPLAY_CURSOR('cbnkw688amax5',2));

image.png
以上

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?