実行計画の固定
はじめに: 実行計画の確認方法
SQLレポートとかでも確認できるが。
set line 200
set pagesize 100
-- 対象のSQSLを実行
select * from sample_users where id = 1;
-- 実行計画の確認
select * from table(dbms_xplan.display_cursor);
実行例:
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID cxzamm8bsb185, child number 0
-------------------------------------
select * from sample_users where id = 1
Plan hash value: 1774215885
--------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 3 (100)| |
| 1 | TABLE ACCESS BY INDEX ROWID| SAMPLE_USERS | 1 | 75 | 3 (0)| 00:00:01 |
|* 2 | INDEX UNIQUE SCAN | SYS_C007998 | 1 | | 2 (0)| 00:00:01 |
--------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
2 - access("ID"=1)
19行が選択されました。
ヒント句
SQL文にヒント句を挿入する方法。
シンプルd差が、SQL文を書き換える必要があるのがデメリット。
また、SQL_IDが変わる。
-- ヒント句を指定して、強制的にフルスキャンに
select /*+ FULL(SAMPLE_USERS) */ * from sample_users where id = 1;
-- 実行計画の確認
select * from table(dbms_xplan.display_cursor);
SQL> select * from table(dbms_xplan.display_cursor);
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
SQL_ID 1yghnm9gw2u66, child number 0
-------------------------------------
select /*+ FULL(SAMPLE_USERS) */ * from sample_users where id = 1
Plan hash value: 3964565270
----------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | | | 301K(100)| |
|* 1 | TABLE ACCESS FULL| SAMPLE_USERS | 1 | 75 | 301K (1)| 00:00:12 | ★ TABLE ACCESS FULLとなっている
----------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
1 - filter("ID"=1)
18行が選択されました。
19c時点で最新(?)の実行計画の固定方法
プランスタビリティ
※ 11g以降非推奨
SQLを書き換えなくともOKな機能。
アウトラインとかを作る方式。
SPM (SQL Plan Management)
19cで最新の(?)固定方法。
ベースラインを使用。
以下、19cではうまくいかない・・なぜ?
-- ベースラインの作成を有効化(デフォルトでFALSE)
show parameter optimizer_capture_sql_plan_baseline;
alter session set optimizer_capture_sql_plan_baseline=true;
-- ベースラインを使用するか(デフォルトでTRUE)
show parameter optimizer_use_sql_plan_baseline;
alter session set optimizer_use_sql_plan_baseline=true;
ベースラインの確認
set line 200
set pagesize 100
col sql_text for a50
col plan_name for a50
col sql_handle for a20
col sql_name for a50
select sql_text, plan_name, sql_handle, enabled, accepted, fixed from dba_sql_plan_baselines;
実行計画識別用のSQL_ID, PLAM_HASH_VALUE確認
select sql_id, plan_hash_value from v$sql_plan where sql_id = 'xxx';
SQL_ID PLAN_HASH_VALUE
------------- ---------------
1kb56hd6c73bv 532132364
1kb56hd6c73bv 532132364
1kb56hd6c73bv 532132364
1kb56hd6c73bv 532132364
:
:
declare
int number;
begin
int := dbms_spm.load_plans_fromcursor_chache(sql_id=>'xxx', plan_hash_value=>'xxxxx')
end;
/