SQL Plan Management Using SQL Plan Baselines in Oracle | Oracle Database Performance Tuning Tutorial -14


I will explain SQL Plan Management Using SQL Plan Baselines in this article.


Most important point in the Performance Tuning is that maintain the SQL performance in spite of the changes. There are lots of changes and factors that influence the Optimizer and execution plan as follows.

  • SQL Profile creation
  • Database upgrade and using new Optimizer
  • Stale statistics
  • Changes on Optimizer parameters
  • Changes on Database settings
  • Changes to schema and metadata



If you don’t know What is the Optimizer and how optimizer works, you should read the following article to learn it detail.



The main task of SQL Plan Management is to prevent performance regressions because of unverifed change to SQL Execution plans. So If the SQL Plan management is active, then there will not be Performance problems even if drastic changes perform.

Optimizer generates alternative plans for each SQL statement, but they are not used immediately. Optimizer try to verify if it produces better performance than current plan, then Optimizer consider it to use, because Only known and verified execution plans are used.


SQL Plan Baselines are the vital objects to prevent performance regressions. Architecture of SQL Plan baseline is as follows.


An Automatic SQL Tuning task collects only TOP SQL statements that are executed more than once. Plan verification is done by the  Automatic SQL Tuning task running as an automated task in a maintenance window.


If you don’t know what is the Automatic SQL Tuning task, you should read the following article.

What is the Automatic SQL Tuning and How to Automated SQL Tuning in Oracle | Oracle Database Performance Tuning Tutorial -12




There are lots of different plans in the plan history generated by the optimizer for any SQL statement. But only some plans in the plan history can be accepted and used which are known and verified.


Loading SQL Plan Baselines

There are two ways  load SQL plan baselines.

Firstly, you can set the OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES initialization parameter to TRUE to use automatic plan capture.


OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES initialization parameter is FALSE by default, so set it as TRUE as follows.


NAME                                 TYPE        VALUE
------------------------------------ ----------- ------------------------------
optimizer_capture_sql_plan_baselines boolean     FALSE


System altered.


Secondly, You can use the DBMS_SPM package to enable manually managing SQL plan baselines.




You can load plans from a SQL Tuning Set as follows.

my_plans pls_integer;
    sqlset_name => 'MSD_STS_TEST');



If you know better plan which is not used by a specific SQL, You can load SQL Plan baseline manually from Cursor Cache as follows.


l_plans_loaded PLS_INTEGER;
l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(
sql_id => '091dz4fc0jj47',plan_hash_value=>4162141870,fixed=>'YES');


If Optimizer considers any SQL Plan, its ENABLED and ACCEPTED  attributes must be set to YES. When any Plan is enabled for use of Optimizer, then ENABLED attribute is set YES. When ACCEPTED attribute is YES, then Optimizer validate this Plan as a good plan.

If FIXED attributes is SET, then Opimizer considers only these plans instead of other plans.

So I have used FIXED=YES in my above example to force using it manually.



You can find Plan_hash_value of any SQL_id with the following Script. This script displays all execution plans, so if your query is not using better, then you can load better plan as SQL Plan Baseline.

select inst_id,SQL_PLAN_BASELINE ,sql_fulltext,sql_profile ,trunc(elapsed_time/decode(executions, 0, 1, executions)/1000000) elapsed_time, plan_hash_value,hash_value, child_number, first_load_time,
last_load_time, executions, buffer_gets, trunc(buffer_gets/decode(executions, 0, 1, executions)) gets_per_exec, trunc(rows_processed/decode(executions, 0, 1,
executions)) rows_return_per_exec
from gv$sql where sql_id='091dz4fc0jj47' order by last_load_time desc;


After loading SQL Plan Baseline, you can execute the SQL and see if SQL Plan Baseline is used or not.


You can query the SQL Plan Baselines by using SQL_TEXT and Plan name as follows.

SELECT * FROM dba_sql_plan_baselines where sql_text like '%SELECT /*+ ALL_ROWS */ T36.CONFLICT_ID,%';

SELECT * FROM dba_sql_plan_baselines where plan_name='SQL_PLAN_046zt02dnhtm8c6bdd030';




You can display SQL Plan Baseline as follows.

DBMS_XPLAN.display_sql_plan_baseline (
plan_name => 'SQL_PLAN_3q32rfc81889n74986091'));


You can alter the SQL Plan baseline parameters as follows.

l_plans pls_integer;
l_plans := dbms_spm.alter_sql_plan_baseline (
sql_handle => 'SQL_6600fe4df5fa16a8',
plan_name => 'SQL_PLAN_6c07y9ruzn5p8dcab14db',
attribute_name => 'fixed',
attribute_value => 'YES'


You can drop the SQL Plan baseline as follows.

Firstly, query the SQL Plan Baselines by using SQL_TEXT and Plan name as follows. Specify which SQL Plan Baseline will be dropped, and what is the sql_handle,plan_name of SQL Plan baseline by executing the following scripts.

SELECT * FROM dba_sql_plan_baselines where sql_text like '%SELECT /*+ ALL_ROWS */ T36.CONFLICT_ID,%';

select sql_handle, plan_name, enabled, accepted, fixed from dba_sql_plan_baselines;
SQL_HANDLE                PLAN_NAME                      ENA  ACC    FIX
SYS_SQL_159d10fcdfedc124  SYS_SQL_PLAN_tyedc741a57b5fc2  YES  NO     NO
SYS_SQL_159d10fcdfedc124  SYS_SQL_PLAN_vbedc741f554c408  YES  YES    NO

Then If you find the sql_handle,plan_name of SQL Plan baseline, you can drop it as follows.

set serveroutput on
my_int pls_integer;
sql_handle => 'SQL_3a19fe140b9d4869',
plan_name =>'SQL_PLAN_2m81syzy7x63x7aa1fbf6');


I will continue to explain Performance tuning tutorial in the next articles.




Do you want to learn Top 30 SQL Tuning Tips and Tricks, then read the following articles.


 803 views last month,  2 views today

About Mehmet Salih Deveci

I am Founder of SysDBASoft IT and IT Tutorial and Certified Expert about Oracle & SQL Server database, Goldengate, Exadata Machine, Oracle Database Appliance administrator with 10+years experience. I have OCA, OCP, OCE RAC Expert Certificates I have worked 100+ Banking, Insurance, Finance, Telco and etc. clients as a Consultant, Insource or Outsource. I have done 200+ Operations in this clients such as Exadata Installation & PoC & Migration & Upgrade, Oracle & SQL Server Database Upgrade, Oracle RAC Installation, SQL Server AlwaysOn Installation, Database Migration, Disaster Recovery, Backup Restore, Performance Tuning, Periodic Healthchecks. I have done 2000+ Table replication with Goldengate or SQL Server Replication tool for DWH Databases in many clients. If you need Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS Consultancy and Training you can send my email adress mehmetsalih.deveci@outlook.com. -                                                                                                                                                                                                                                                 - Oracle DBA, SQL Server DBA, APPS DBA,  Exadata, Goldengate, EBS ve linux Danışmanlık ve Eğitim için  mehmetsalih.deveci@outlook.com a mail atabilirsiniz.

Check Also


enq: TM – contention | TM Contention Wait Events in Oracle

Hi, I will explain enq: TM – contention | TM Contention Wait Events in Oracle …

Leave a Reply