Share

Execution plan fixing in Oracle databases

In some cases in Oracle databases, queries may run with bad plans due to optimizers not being able to make the right decision. If there is a better plan, fixing may be required for the query to run with this plan. A query’s plan can be fixed by following the steps below. In other words, the plan fix operation can be performed.

First, check that the values ​​of the following parameters in the database are as specified.

OPTIMIZER_USE_SQL_PLAN_BASELINES = TRUE

OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES = FALSE

 

 

If the parameters are not like this, change them. Then check the query plans regarding the sql_id information with the query below.

select inst_id,
       address,
       hash_value,
       sql_id,
       plan_hash_value,
       Operation,
       optimizer,
       cost
  from gv$sql_plan
 where id = 0
   and sql_id = 'XXXXXXXXXXX';

Afterwards, let’s load the existing plan of the relevant SQL statement in the cursor cache with the pl/sql block below.

declare
  my_plans pls_integer;
begin
  my_plans := dbms_spm.load_plans_from_cursor_cache(sql_id => 'XXXXXXXXXXX',
                                                        plan_hash_value => 'XXXXX',
                                                       fixed => 'NO');
end;

or

declare
  my_plans pls_integer;
begin
  my_plans := dbms_spm.load_plans_from_cursor_cache(sql_id => 'XXXXXXXXXXX');
end;

Afterwards, let’s determine the sql_handle and plan_name information from the created sql baseline information with the following query.

select * from dba_sql_plan_baselines;

Let’s fix the plan of our query with the sql_handle and plan_name information returned from the query above, using the pl/sql block below.

DECLARATION
  l_plans_altered PLS_INTEGER;
BEGIN
  l_plans_altered := DBMS_SPM.alter_sql_plan_baseline(sql_handle => 'SQL_aaa4f03be3519ae5',
                                                      plan_name => 'SQL_PLAN_ap97h7gjp36r5e4cd1512',
                                                      attribute_name => 'fixed',
                                                      attribute_value => 'YES');
  DBMS_OUTPUT.put_line('Plan fixed : ' || l_plans_altered);
END;
/

 

You can delete the created sql baseline as follows.

DECLARE l_plans_dropped PLS_INTEGER;
BEGIN
l_plans_dropped := DBMS_SPM.drop_sql_plan_baseline (sql_handle => 'SQL_aaa4f03be3519ae5',plan_name => 'SQL_PLAN_ap97h7gjp36r5e4cd1512'); DBMS_OUTPUT.put_line('Plans Dropped: ' || l_plans_dropped);
END; /

Loading

You may also like