Skip to main content

Oracle SQL Plan baseline

Use plan baseline to stabilize query plan.

I use the following two links as reference.
http://rnm1978.wordpress.com/2011/06/28/oracle-11g-how-to-force-a-sql_id-to-use-a-plan_hash_value-using-sql-baselines/

http://kerryosborne.oracle-guy.com/2009/04/oracle-11g-sql-plan-management-sql-plan-baselines/

step 1: find the problem query which use bad query plan rather than the good plan.

step 2: find the snapshot id which has has the good plan plan for this sql_id.

VARIABLE cnt NUMBER
EXECUTE :cnt := DBMS_SPM.LOAD_PLANS_FROM_CURSOR_CACHE( -
                    sql_id => '0yv4z9c24ywm6');

set lines 155
col execs for 999,999,999
col avg_etime for 999,999.999
col avg_lio for 999,999,999.9
col begin_interval_time for a30
col node for 99999
break on plan_hash_value on startup_time skip 1
select ss.snap_id, ss.instance_number node, begin_interval_time, sql_id, plan_hash_value,
nvl(executions_delta,0) execs,
(elapsed_time_delta/decode(nvl(executions_delta,0),0,1,executions_delta))/1000000 avg_etime,
(buffer_gets_delta/decode(nvl(buffer_gets_delta,0),0,1,executions_delta)) avg_lio
from DBA_HIST_SQLSTAT S, DBA_HIST_SNAPSHOT SS
where sql_id = nvl('&sql_id','0yv4z9c24ywm6')
and ss.snap_id = S.snap_id
and ss.instance_number = S.instance_number
and executions_delta > 0
order by 1, 2, 3

    SNAP_ID   NODE BEGIN_INTERVAL_TIME            SQL_ID        PLAN_HASH_VALUE        EXECS    AVG_ETIME        AVG_LIO
---------- ------ ------------------------------ ------------- --------------- ------------ ------------ --------------
       101      1 07-NOV-14 03.00.33.289 AM      0yv4z9c24ywm6      4002210582            1      120.021      678,900.0
       140      1 08-NOV-14 06.00.04.247 PM      0yv4z9c24ywm6                            1      261.454    1,461,532.0
       199      1 11-NOV-14 05.00.34.552 AM      0yv4z9c24ywm6                            1      228.954    1,465,972.0
       229      1 12-NOV-14 11.00.04.839 AM      0yv4z9c24ywm6                            1      109.027      688,335.0
       246      1 13-NOV-14 04.00.03.837 AM      0yv4z9c24ywm6                            1      134.105      690,626.0

step 3: create a tuning set.

BEGIN
  DBMS_SQLTUNE.DROP_SQLSET(
    sqlset_name => 'MySTS01');
END;

-- Create SQL Tuning Set (STS)
BEGIN
  DBMS_SQLTUNE.CREATE_SQLSET(
    sqlset_name => 'MySTS01',
    description => 'SQL Tuning Set for loading plan into SQL Plan Baseline');
END;

step 4:

populate the tning set with the snapshot, try to use a broader range of snapshot id from step 2
-- Populate STS from AWR, using a time duration when the desired plan was used
--  List out snapshot times using :
SELECT SNAP_ID, BEGIN_INTERVAL_TIME, END_INTERVAL_TIME
FROM dba_hist_snapshot ORDER BY END_INTERVAL_TIME DESC;
--  Specify the sql_id in the basic_filter (other predicates are available, see documentation)
DECLARE
  cur sys_refcursor;
BEGIN
  OPEN cur FOR
    SELECT VALUE(P)
    FROM TABLE(
       dbms_sqltune.select_workload_repository(begin_snap=>92440, end_snap=>92460,basic_filter=>'sql_id = ''0mdxgv8ks2pbc''',attribute_list=>'ALL')) p;
     DBMS_SQLTUNE.LOAD_SQLSET( sqlset_name=> 'MySTS01', populate_cursor=>cur);
  CLOSE cur;
END;
/

step 5: verify that the tuning set has the sql_id
-- List out SQL Tuning Set contents to check we got what we wanted
SELECT
  first_load_time          ,
  executions as execs              ,
  parsing_schema_name      ,
  elapsed_time  / 1000000 as elapsed_time_secs  ,
  cpu_time / 1000000 as cpu_time_secs           ,
  buffer_gets              ,
  disk_reads               ,
  direct_writes            ,
  rows_processed           ,
  fetches                  ,
  optimizer_cost           ,
  sql_plan                ,
  plan_hash_value          ,
  sql_id                   ,
  sql_text
   FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET(sqlset_name => 'MySTS01')
             );

step 6:  verify that the good plan_hash_value is in the tuning set.

select sql_id,plan_hash_value FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET(sqlset_name => 'MySTS01'));
12:09:12 RMS81> select sql_id,plan_hash_value FROM TABLE(DBMS_SQLTUNE.SELECT_SQLSET(sqlset_name => 'MySTS01'));

SQL_ID        PLAN_HASH_VALUE
------------- ---------------
0yv4z9c24ywm6      4002210582

step 7: load the plan.

-- List out the Baselines to see what's there
SELECT * FROM dba_sql_plan_baselines ;

-- Load desired plan from STS as SQL Plan Baseline
-- Filter explicitly for the plan_hash_value here if you want
DECLARE
my_plans pls_integer;
BEGIN
  my_plans := DBMS_SPM.LOAD_PLANS_FROM_SQLSET(
    sqlset_name => 'MySTS01',
    basic_filter=>'plan_hash_value = ''87655762'''
    );
END;
/

step 8: fix the plan.

DECLARE
my_plans pls_integer;
BEGIN
my_plans := DBMS_SPM.ALTER_SQL_PLAN_BASELINE (
sql_handle  => NULL,
plan_name   => ‘SQL_PLAN_8f56b2ffswhrpb8e5e62d’,
attribute_name => ‘fixed’,
attribute_value => ‘YES’);
END;
/

step 9: verify the plan is fixed.

12:24:31 RMS81>  exec print_table('select * from dba_sql_plan_baselines where sql_handle=''SQL_8714cb139d8e42f5''')
SIGNATURE                     : 6340198085419112112
SQL_HANDLE                    : SQL_57fce8911f0496b0
SQL_TEXT                      : INSERT /*+ APPEND */ INTO WOSTAGE.WO_STAGING_REV_SHARE SELECT B.FISCAL_PERIOD , B.STATION_INT , B.STATION_CALL_LETTERS
 ,
B.CHANNEL_INT , B.STATION_CALL_LETTERS||' '||A.REPORTING_NAME , B. REVTYPE_CODE
PLAN_NAME                     : SQL_PLAN_5gz78k4gh95ph66848240
CREATOR                       : CTVDBA
ORIGIN                        : MANUAL-LOAD
PARSING_SCHEMA_NAME           : WOSTAGE
DESCRIPTION                   :
VERSION                       : 11.2.0.3.0
CREATED                       : 15-NOV-14 12.10.10.000000 PM
LAST_MODIFIED                 : 15-NOV-14 12.24.31.000000 PM
LAST_EXECUTED                 :
LAST_VERIFIED                 :
ENABLED                       : YES
ACCEPTED                      : YES
FIXED                         : YES
REPRODUCED                    : YES
AUTOPURGE                     : YES
OPTIMIZER_COST                : 1934711
MODULE                        : JDBC Thin Client
ACTION                        :
EXECUTIONS                    : 1
ELAPSED_TIME                  : 120021019
CPU_TIME                      : 15880520
BUFFER_GETS                   : 678900
DISK_READS                    : 721160
DIRECT_WRITES                 : 55781
ROWS_PROCESSED                : 9196
FETCHES                       : 0
END_OF_FETCH_COUNT            : 1
-----------------

PL/SQL procedure successfully completed.

Elapsed: 00:00:00.06
12:24:47 RMS81>

The following scripts can be used to migrate plan baseline.

DECLARE
  v_dropped_plans number;
BEGIN
  v_dropped_plans := DBMS_SPM.DROP_SQL_PLAN_BASELINE (
     sql_handle => 'SQL_0cf31d9f7b33b119'
);
  DBMS_OUTPUT.PUT_LINE('dropped ' || v_dropped_plans || ' plans');
END;
/

    DECLARE
       i number;
    BEGIN
       DBMS_SPM.create_stgtab_baseline
       ( table_name  => 'XXFND_SQL_PLAN_BASELINES'
       , table_owner => 'WOSTAGE'
       ) ;
    END;

 DECLARE
       l_ret_value NUMBER;
   BEGIN
       l_ret_value := DBMS_SPM.pack_stgtab_baseline
                      ( table_name  => 'XXFND_SQL_PLAN_BASELINES'
                      , table_owner => 'WOSTAGE'
                      , enabled     => 'YES'
                      , accepted    => 'YES'
                      ) ;
   END;

   declare
      i number ;
   begin
      i := dbms_spm.unpack_stgtab_baseline
           ( table_name => 'xxfnd_sql_plan_baselines'  
           , table_owner => 'WOSTAGE'
           ) ;
      dbms_output.put_line('Plans Loaded : ' || i);
   end;

Comments

Popular posts from this blog

Opatch apply/lsinventory error: oneoff is corrupted or does not exist

I am applying the quarterly patch for 19c RDBMS, I tried using napply but failed, but somehow it corrupted the inventory though nothing applied. further apply and lsinventory command ran into error like this: $ ./OPatch/opatch lsinventory Oracle Interim Patch Installer version 12.2.0.1.21 Copyright (c) 2020, Oracle Corporation.  All rights reserved. Oracle Home       : /u02/app/oracle/19.0.0 Central Inventory : /u01/app/oraInventory    from           : /u02/app/oracle/19.0.0/oraInst.loc OPatch version    : 12.2.0.1.21 OUI version       : 12.2.0.7.0 Log file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/opatch2020-09-08_13-35-59PM_1.log Lsinventory Output file location : /u02/app/oracle/19.0.0/cfgtoollogs/opatch/lsinv/lsinventory2020-09-08_13-35-59PM.txt -------------------------------------------------------------------------------- Inventory load failed... OPatch cannot load inventory ...

oracle dba_hist_sysmetric_summary

found this blog is helpful to get CPU and IO statistics on oracle database. http://shob-dbadmin.blogspot.ca/2012/12/how-to-find-total-io-of-database.html courtesy to  Shomil Bansal , below are hist writing, not mine. How to find total IO of the database instance Total IO of database instance is sum of the physical reads, physical writes and redo writes. There are several views to find these values. v$sysmetric  - Reports metric values for only the most current time sample 60 secs. v$sysmetric_summary  - Reports metric values for time sample of 1 hour. v$sysmetric_history  - Reports metric values every 60 sec from the time instance is up. Better way to analyse IO using this view to take deltas between two time periods. dba_hist_sysmetric_history  - All the above views are refreshed when the instance is restarted. This view, part of AWR, stores the historical stats. I have used this view for my report. Query: ====== set lines 350...

ORA_RMAN_SGA_TARGET

assume that we lost all the files of oracle database but we do have rman backup, when trying to bring up a dummy database before restore start, I get this error. RMAN> startup nomount force; WARNING: cannot translate ORA_RMAN_SGA_TARGET value startup failed: ORA-01078: failure in processing system parameters ORA-01565: error in identifying file '+DATA/PROD/spfilePROD.ora' ORA-17503: ksfdopn:2 Failed to open file +DATA/PROD/spfilePROD.ora ORA-15056: additional error message ORA-17503: ksfdopn:DGOpenFile05 Failed to open file +DATA/prod/spfileprod.ora ORA-17503: ksfdopn:2 Failed to open file +DATA/prod/spfileprod.ora ORA-15173: entry 'spfileprod.ora' does not exist in directory 'prod' ORA-06512: at line 4 starting Oracle instance without parameter file for retrival of spfile RMAN-00571: =========================================================== RMAN-00569: =============== ERROR MESSAGE STACK FOLLOWS =============== RMAN-00571: =================================...