Oracle 11g SQL Plan Management(原创)

SQL Plan Management

Once the cost optimizer provides an efficient execution plan for a SQL statement, you can’t assume that the optimizer will always use that execution plan. There may be any number of changes in the database, ranging from changes such as the addition or deletion of an index, changes in the composition of data that affects factors such as selectivity and cardinality, to the obvious changes such as a database or server upgrade. In previous releases, Oracle provided the stored outlines feature to preserve SQL execution plans to prevent unexpected performance deterioration caused by a major system change such as a database upgrade. In Oracle Database 11g, Oracle provides a brand-new feature called SQL Plan Management (SPM), to preserve SQL performance across major system changes. You can use SPM to preserve SQL performance when you encounter the following types of system changes:

  • Database upgrades
  • New optimizer versions
  • Changes in optimizer parameters
  • Changes in system settings
  • Changes in schema and metadata definitions
  • Deployment of new application modules

Although the SQL Tuning Advisor does provide you SQL profiles to improve SQL performance of high-load statements, that’s done only after the database identifies the SQL statements as poor performing. If the poor performance resulted from an execution plan change brought about by one of the large sets of factors that influence the explain plan, you still have to wait for the ADDM to capture the bad SQL statements and for the Automatic SQL Tuning Advisor to tune that statement. This, in other words, is a reactive mechanism at best, to cope with poorly performing SQL statements. Using stored outlines is a practical alternative, but also requires manual intervention. Oracle intends SPM as a preventative mechanism from the outset. The database automatically controls SQL plan evolution with the help of what are called SQL plan baselines. SPM’s job is to capture and evaluate the execution plans over time and build SQL plan baselines containing only efficient execution plans. A new execution plan will be allowed to be part of the SQL plan baseline for a specified SQL statement only if the new plan doesn’t cause performance regression. During the execution of any SQL statement, only a plan that’s a part of that SQL statement’s SQL plan baseline can be selected for execution. The database uses these SQL plan baselines to preserve the SQL statement performance in the face of system changes such as the ones listed previously. The goal is to avoid plan regressions, while minimizing the time that you have to spend tracking down and analyzing SQL performance regressions and fixing them. The SQL plan verification is managed by the new automated maintenance task, Automatic SQL Tuning Advisor.

SQL Plan Baselines

A SQL plan baseline is a set of all accepted plans in the plan history that the database maintains for each repeatable SQL statement that the database executes. The plan history contains all the SQL Plans generated for a particular SQL statement over time by the optimizer, but only some of those plans may be accepted plans. The database maintains a plan history for only repeatable SQL statements, but not for ad-hoc statements. This plan history thus contains all the plans generated for a specific SQL statement over time and is the key to determining whether a plan has been changing over time and if newer versions are better than the previous plan versions stored in the plan history. The plan history includes all information used by the optimizer when figuring out an optimal execution plan, including information regarding the SQL text, bind variables, and the environment in which the SQL statement is being compiled. Earlier, I said that the SQL plan baseline consists of the set of accepted plans for a SQL statement. The database defines a plan as acceptable when it verifies that the plan doesn’t lead to a performance regression when compared to the other plans in the plan history. Note that the very first execution plan the database generates for a SQL statement is always considered acceptable by the optimizer and becomes the original SQL plan baseline as well as the plan history for that statement. Later execution plans for that statement will automatically become part of the plan history but not the SQL plan baseline initially.

The database will include them in the SQL plan baseline only if it verifies that they don’t lead to a performance regression. The database verifies SQL plans as part of the Automatic SQL Tuning task that runs as one of the automated tasks in the maintenance windows. You don’t have to configure this automatic verification of SQL plans by the database. The Automatic SQL Tuning aims strictly at high load SQL statements and automatically converts a successfully verified plan into an accepted plan.

Using SQL plan baselines helps minimize potential performance regressions and stabilize SQL performance over time. Oracle Database 11g provides the new package DBMS_SPM to support the SQL Plan Management feature. Of course, you can also use the Enterprise Manager to manage SPM.

Capturing SQL Plan Baselines

You capture SQL plan baselines by either having the database automatically capture SQL plans or you can manually load them yourself.

Automatic Plan Capture

Set the new initialization parameter optimizer_capture_sql_plan_ baselines to true to let the datable automatically create and maintain a SQL plan history. By default, this parameter is set to a value of false. Because the parameter is dynamic, you can enable automatic SQL plan capturing on-the-fly, with the following statement:

SQL> alter system set optimizer_use_sql_plan_baselines=true;
System altered.

Once you set the optimizer_capture_sql_plan_baselines parameter to true, as shown here, the database will automatically recognize all repeatable SQL statements and capture the SQL plans for those SQL queries for each SQL statement. Setting the parameter to true will also generate SQL plan baselines for the repeatable SQL statements. The database will automatically create a plan history for each repeatable SQL statement when you set the optimizer_capture_sql_plan_baselines parameter to true. Of course, as explained earlier, the very first SQL plan that the database generates for any SQL statement is automatically integrated into the corresponding SQL plan baseline. You can use the automatic SQL plan capturing mechanism to retain good execution plans for use after a database upgrade. Once you complete the upgrade to Oracle Database 11g, for example, leave the optimizer_features_enable parameter set to 10.2 (or whatever release you upgraded from, as long as it’s at least equal to 10.0.0, which is the minimum level you can set the compatible parameter to). The SQL Plan Management feature will collect the pre-Oracle Database 11g execution plans and store them as SQL plan baselines in the upgraded database. Once you’re sure that the database has had a chance to capture all the necessary SQL plan baselines, you can set the optimizer_features_enable parameter to 11.1, to take advantage of the new features offered by Oracle Database 11g. You can thus have your cake and eat it too, because you’ll be taking advantage of the new features without suffering a possible performance regression of the SQL statements.

Manual Plan Loading

You can use manual plan loading instead of, or together with, automatic plan capture. There is a major difference between manual plan loading and automatic loading of plans. When you load plans manually, the database doesn’t verify them for performance. It immediately adds the plans you manually load as accepted plans to the SQL plan baseline. One of the biggest worries when upgrading to a new release of the Oracle database is the possibility of SQL plan regressions following the use of the new optimizer. You can now cross this hurdle either by capturing the current SQL plans manually and exporting them to the target database after the upgrade or by first capturing your SQL workload into SQL tuning sets before upgrading the database. Once the database upgrade is completed, you can bulk load the SQL plans into the SQL plan baselines. Note that even though you start off with manual bulk loading of the SQL execution plans, you can still have the database automatically capture SQL plans from that point on. There are two basic ways you can manually load SQL plans to create SQL plan baselines—using a SQL Tuning Set (STS) and AWR snapshots and loading from the database cursor cache.To load plans from Automatic Workload Repository (AWR), load the plans stored in AWR snapshots into a SQL tuning set before using the LOAD_PLANS_FROM_SQLSET function. In both cases, you make use of the DBMS_SPM package to manually manage the SQL plan baselines.

Loading SQL Plans from a SQL Tuning Set  

In order to load plans from an STS, use the LOAD_PLANS_FROM_SQLSET function of the DBMS_SPM package, as shown in the following set of steps:

Create an empty SQL Tuning Set, as shown here:

begin
  dbms_sqltune.create_sqlset(
    sqlset_name  => 'testset1',
    description  => 'Test STS to capture AWR Data');
end;
/

You can now use the STS you just created to load selected SQL statements from the AWR. If you’re loading plans from a remote database, you can load the plans into the STS first and then export and import the STS into the target database where you want to load the SQL plans.

declare
  test_cursor1  dbms_sqltune.sqlset_cursor;
begin
  open test_cursor1 for
  select value(p) from table(dbms_sqltune.select_workload_repository(
  'SYSTEM_MOVING_WINDOW',null,null,null,null,null,null,20))p;
  dbms_sqltune.load_sqlset(
    sqlset_name  => 'testset1',
    populate_cursor  => test_cursor1);
end;
/

Before you can load the top 20 SQL statements into the STS, you must first select them from the AWR baseline using a ref cursor and a predefined table function to select the columns you need. The STS testset1 now contains the top 20 SQL statements in the AWR, ordered by elapsed time.

In order to load the SQL plans from the STS as SQL plan baselines, use the LOAD_PLANS_FROM_SQLSET function of the DBMS_SPM package:

declare
  test_plans  pls_integer;
begin
  test_plans  := dbms_spm.load_plans_from_sqlset(sqlset_name  => 'testset1');
end;
/

Loading SQL Plans from the Cursor Cache

Instead of using an STS to load SQL plans, you can use the cursor cache to directly load the plans or the SQL statements stored in the cache. Here’s the syntax of the LOAD_PLANS_FROM_ CURSOR_CACHE function:

declare
  l_plans_loaded  PLS_INTEGER;
begin
  l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(
    sql_id  => '6r95ktyt1vgmg');
end;
/

Selecting SQL Plan Baselines

Once you collect the SQL plans either from the AWR or from the cursor cache, the next step is to enable use of the SQL plan baselines. To do this, you must ensure the optimizer_use_sql_plan_baselines initialization parameter to true. The parameter is set to true by default, meaning SQL plan baselines are enabled by default. When the optimizer compiles any SQL statements, it follows a conservative explain plan selection strategy when you use SQL plan baselines, which I summarize here.

Note the differences between optimizer_capture_sql_plan_baselines and optimizer_use_ sql_plan_baselines

  • When the database recognizes a new SQL statement as a repeatable statement for the first time, it adds the lowest cost plan for that statement to the SQL plan baseline for that statement. The database will then use this SQL plan baseline to execute the SQL statement.
  • When the initialization parameter optimizer_use_sql_plan_ baselines is set to its default value of true, it enables the use of the SQL plan baselines stored by the database in the SQL Management Base (SMB). The optimizer will look for a SQL plan baseline for the SQL statement the database is compiling. If a SQL plan baseline exists for that SQL statement, the database uses a comparative plan selection policy—that is, the optimizer will figure out the cost of each of the baseline plans and pick the one with the lowest cost. The optimizer will create a best cost plan and try to match it to a plan in the SQL plan baseline. If it finds a match, it goes ahead and executes the statement using the best cost plan. If the database fails to match the best cost plan with any plan in the SQL plan baseline, it will add the new plan to the plan history as a non-accepted plan first. So it is not used until it is verified not to cause a reduction in performance.  It then chooses the lowest cost plan from the set of accepted plans in the SQL plan baseline and executes the statement using that plan for the statement after comparing it with all the accepted plans in the SQL plan baseline.
  • In reality, only the outline for each plan is stored in the SMB. Therefore, the optimizer will reproduce the actual execution plan from the stored outline of the selected plan and execute the statement using that plan. If the database can’t reproduce any of the accepted plans in the baseline, say because you dropped an index, then the optimizer uses the lowest cost plan for a newly compiled SQL statement 
  • The end result is that the optimizer will always produce a plan that’s either the best cost plan or a baseline plan. You can query the OTHER_XML column in the PLAN_TABLE after running an explain plan on a SQL statement, to find out exactly what strategy the optimizer has adopted in a specific case.

You can view the execution plan for the specified SQL_HANDLE of a plan baseline by executing the DBMS_XPLAIN.DISPLAY_SQL_PLAN_BASELINE function.

SQL> select * from table(
                dbms_xplan.display_sql_plan_baseline(
                  sql_handle  => 'SYS_SQL_0265b48f47be1bcf',
                  format      => 'basic'));
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
SQL handle: SYS_SQL_0265b48f47be1bcf
SQL text: select cols,audit$,textlength,intcols,property,flags,rowid from view$
          where obj#=:1
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
Plan name: SQL_PLAN_04tdnjx3vw6yg56801109         Plan id: 1451233545
Enabled: NO      Fixed: NO      Accepted: YES     Origin: MANUAL-LOAD
--------------------------------------------------------------------------------
PLAN_TABLE_OUTPUT
--------------------------------------------------------------------------------
Plan hash value: 749386351
-----------------------------------------------
| Id  | Operation                   | Name    |
-----------------------------------------------
|   0 | SELECT STATEMENT            |         |
|   1 |  TABLE ACCESS BY INDEX ROWID| VIEW$   |
|   2 |   INDEX UNIQUE SCAN         | I_VIEW1 |
-----------------------------------------------
21 rows selected.

If you’re using a fixed plan, the explain plan for that statement will indicate at the end that the plan is a fixed plan.

Evolving SQL Plan Baselines

The database routinely evaluates new plan performance with a view to integrating plans with superior performance into the SQL plan baseline for the corresponding SQL statement. Evolving SQL plan baselines is the critical phase when the database changes a non-accepted plan in the plan history to an accepted plan and makes it part of the SQL plan baseline. In order to deem a plan in the history an accepted plan, its performance must be better than already accepted plans that are in the SQL plan baseline.

To successfully verify a non-accepted plan, the database compares the plan’s performance to that of a plan it selects from the SQL plan baseline and ensures that the former delivers superior performance. You need to formally evolve a SQL plan baseline only if you’re using automatic plan  capture. If you’re using the manual capture process through an STS or a cursor cache, the moment you load a new plan into a SQL plan baseline, they are considered accepted plans and thus don’t have to go through the evolution process described here. You must, however, formally evolve all SQL plans that the database captures automatically. You can evolve SQL plan baselines in two ways: with the EVOLVE_SQL_PLAN_ BASELINE function or the SQL Tuning Advisor.

Using the EVOLVE_SQL_PLAN_BASELINE Function   

The EVOLVE_ SQL_PLAN_BASELINE function determines whether a new plan added to the plan history performs better than a plan from the corresponding SQL plan baseline. If so, it adds the new plan to the SQL plan baseline as an accepted plan. The following query uses the EVOLVE_SQL_PLAN_BASELINE function to evolve the SQL plan baseline and output the associated report.Here’s an example: 

This section represents a step-by-step example of using SQL plan baselines. It uses manual loading, so switch off automatic plan capture.
CONN sys/password@db11g AS SYSDBA
ALTER SYSTEM SET OPTIMIZER_CAPTURE_SQL_PLAN_BASELINES=FALSE;
Create and populate a test table.
CONN test/test@db11g
CREATE TABLE spm_test_tab (
  id           NUMBER,
  description  VARCHAR2(50)
);
DECLARE
  TYPE t_tab IS TABLE OF spm_test_tab%ROWTYPE;
  l_tab t_tab := t_TAB();
BEGIN
  FOR i IN 1 .. 10000 LOOP
    l_tab.extend;
    l_tab(l_tab.last).id := i;
    l_tab(l_tab.last).description := 'Description for ' || i;
  END LOOP;
  FORALL i IN l_tab.first .. l_tab.last
    INSERT INTO spm_test_tab VALUES l_tab(i);
  COMMIT;
END;
/
EXEC DBMS_STATS.gather_table_stats(USER, 'SPM_TEST_TAB', cascade=>TRUE);
Query the table using an unindexed column, which results in a full table scan.
SET AUTOTRACE TRACE
SELECT description
FROM   spm_test_tab
WHERE  id = 99;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=13 Card=1 Bytes=24)
   1    0   TABLE ACCESS (FULL) OF 'SPM_TEST_TAB' (TABLE) (Cost=13 Card=1 Bytes=24)
Identify the SQL_ID of the SQL statement by querying the V$SQL view.
CONN sys/password@db11g AS SYSDBA
SELECT sql_id
FROM   v$sql
WHERE  sql_text LIKE '%spm_test_tab%'
AND    sql_text NOT LIKE '%dba_sql_plan_baselines%'
AND    sql_text NOT LIKE '%EXPLAIN%';
SQL_ID
-------------
gat6z1bc6nc2d
1 row selected.
Use this SQL_ID to manually load the SQL plan baseline.
SET SERVEROUTPUT ON
DECLARE
  l_plans_loaded  PLS_INTEGER;
BEGIN
  l_plans_loaded := DBMS_SPM.load_plans_from_cursor_cache(
    sql_id => 'gat6z1bc6nc2d');
  DBMS_OUTPUT.put_line('Plans Loaded: ' || l_plans_loaded);
END;
/
Plans Loaded: 1
PL/SQL procedure successfully completed.
The DBA_SQL_PLAN_BASELINES view provides information about the SQL plan baselines. We can see there is a single plan associated with our baseline, which is both enabled and accepted.
CONN sys/password@db11g AS SYSDBA
SELECT sql_handle, plan_name, enabled, accepted
FROM   dba_sql_plan_baselines
WHERE  sql_text LIKE '%spm_test_tab%'
AND    sql_text NOT LIKE '%dba_sql_plan_baselines%';
SQL_HANDLE                     PLAN_NAME                      ENA ACC
------------------------------ ------------------------------ --- ---
SYS_SQL_7b76323ad90440b9       SYS_SQL_PLAN_d90440b9b65c37c8  YES YES
1 row selected.
Flush the shared pool to force another hard parse, create an index on the ID column, then repeat the query to see the affect on the execution plan.
CONN sys/password@db11g AS SYSDBA
ALTER SYSTEM FLUSH SHARED_POOL;
CONN test/test@db11g
CREATE INDEX spm_test_tab_idx ON spm_test_tab(id);
EXEC DBMS_STATS.gather_table_stats(USER, 'SPM_TEST_TAB', cascade=>TRUE);
SET AUTOTRACE TRACE
SELECT description
FROM   spm_test_tab
WHERE  id = 99;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=HINT: ALL_ROWS (Cost=13 Card=1 Bytes=24)
   1    0   TABLE ACCESS (FULL) OF 'SPM_TEST_TAB' (TABLE) (Cost=13 Card=1 Bytes=24)
Notice the query doesn't use the newly created index, even though we forced a hard parse. Looking at the DBA_SQL_PLAN_BASELINES view we can see why.
CONN sys/password@db11g AS SYSDBA
SELECT sql_handle, plan_name, enabled, accepted
FROM   dba_sql_plan_baselines
WHERE  sql_handle = 'SYS_SQL_7b76323ad90440b9';
SQL_HANDLE                     PLAN_NAME                      ENA ACC
------------------------------ ------------------------------ --- ---
SYS_SQL_7b76323ad90440b9       SYS_SQL_PLAN_d90440b9b65c37c8  YES YES
SYS_SQL_7b76323ad90440b9       SYS_SQL_PLAN_d90440b9ed3324c0  YES NO
2 rows selected.
The SQL plan baseline now contains a second plan, but it has not yet been accepted.
Note: If you don't see the new row in the DBA_SQL_PLAN_BASELINES view go back and rerun the query from "spm_test_tab" until you do. It sometimes takes the server a few attempts before it notices the need for additional plans.
The following query uses the EVOLVE_SQL_PLAN_BASELINE function to evolve the SQL plan baseline and output the associated report.
CONN sys/password@db11g AS SYSDBA
SET LONG 10000
SELECT DBMS_SPM.evolve_sql_plan_baseline(sql_handle => 'SYS_SQL_7b76323ad90440b9')
FROM   dual;
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SYS_SQL_7B76323AD90440B9')
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
                        Evolve SQL Plan Baseline Report
-------------------------------------------------------------------------------
Inputs:
-------
  SQL_HANDLE = SYS_SQL_7b76323ad90440b9
  PLAN_NAME  =
  TIME_LIMIT = DBMS_SPM.AUTO_LIMIT
  VERIFY     = YES
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SYS_SQL_7B76323AD90440B9')
--------------------------------------------------------------------------------
  COMMIT     = YES
Plan: SYS_SQL_PLAN_d90440b9ed3324c0
-----------------------------------
  Plan was verified: Time used .05 seconds.
  Passed performance criterion: Compound improvement ratio >= 15.4.
  Plan was changed to an accepted plan.
                      Baseline Plan      Test Plan     Improv. Ratio
                      -------------      ---------     -------------
  Execution Status:        COMPLETE       COMPLETE
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SYS_SQL_7B76323AD90440B9')
--------------------------------------------------------------------------------
  Rows Processed:                 1              1
  Elapsed Time(ms):               2              0
  CPU Time(ms):                   2              0
  Buffer Gets:                   46              3             15.33
  Disk Reads:                     0              0
  Direct Writes:                  0              0
  Fetches:                        0              0
  Executions:                     1              1
-------------------------------------------------------------------------------
                                 Report Summary
DBMS_SPM.EVOLVE_SQL_PLAN_BASELINE(SQL_HANDLE=>'SYS_SQL_7B76323AD90440B9')
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Number of SQL plan baselines verified: 1.
Number of SQL plan baselines evolved: 1.
1 row selected.
The DBA_SQL_PLAN_BASELINES view shows the second plan as been accepted.
CONN sys/password@db11g AS SYSDBA
SELECT sql_handle, plan_name, enabled, accepted
FROM   dba_sql_plan_baselines
WHERE  sql_handle = 'SYS_SQL_7b76323ad90440b9';
SQL_HANDLE                     PLAN_NAME                      ENA ACC
------------------------------ ------------------------------ --- ---
SYS_SQL_7b76323ad90440b9       SYS_SQL_PLAN_d90440b9b65c37c8  YES YES
SYS_SQL_7b76323ad90440b9       SYS_SQL_PLAN_d90440b9ed3324c0  YES YES
2 rows selected.
Repeating the earlier test shows the more efficient plan is now available for use.
CONN test/test@db11g
SET AUTOTRACE TRACE
SELECT description
FROM   spm_test_tab
WHERE  id = 99;
Execution Plan
----------------------------------------------------------
   0      SELECT STATEMENT Optimizer=ALL_ROWS (Cost=2 Card=1 Bytes=24)
   1    0   TABLE ACCESS (BY INDEX ROWID) OF 'SPM_TEST_TAB' (TABLE) (Cost=2 Card=1 Bytes=24)
   2    1     INDEX (RANGE SCAN) OF 'SPM_TEST_TAB_IDX' (INDEX) (Cost=1 Card=1)

Transferring SQL Plan Baselines

Dropping Plans and Baselines
The DROP_SQL_PLAN_BASELINE function can drop a specific plan from a baseline, or all plans if the plan name is not specified.
CONN sys/password@db11g AS SYSDBA
SET SERVEROUTPUT ON
DECLARE
  l_plans_dropped  PLS_INTEGER;
BEGIN
  l_plans_dropped := DBMS_SPM.drop_sql_plan_baseline (
    sql_handle => NULL,
    plan_name  => 'SYS_SQL_7b76323ad90440b9');
   
  DBMS_OUTPUT.put_line(l_plans_dropped);
END;
/

Evolving SQL Plans with the SQL Tuning Advisor

You can also evolve SQL plan baselines by running the SQL Tuning Advisor. This applies to both manual and automatic executions of the SQL Tuning Advisor task. When the SQL Tuning Advisor recommends accepting a SQL profile, it does so because the explain plan with the SQL profile is better than the original explain plan for the untuned statement. Once you accept the SQL profile recommendation and implement it, the advisor automatically adds the plan to the SQL plan baseline for that SQL statement.

Fixed SQL Plan Baselines

If a SQL plan baseline contains one or more enabled plans for which the fixed attribute value is set to yes, the baseline is considered fixed. You can set the fixed attribute to YES for any plan you want, thereby limiting the set of possible plans for a given SQL statement. You usually fix one plan per baseline and, because the optimizer will give preference to the fixed plans over the nonfixed implications of marking a plan as fixed when there are multiple plans that are marked as fixedplans in the SQL plan baseline, it will use the fixed plan. Remember that this will make the optimizer pick the fixed plan even if some of the nonfixed plans are actually cheaper, with a lower cost of execution.  The database doesn’t evolve a fixed SQL plan baseline because the optimizer doesn’t add any new execution plans to a fixed SQL plan baseline. You may, however, evolve even a fixed SQL plan baseline by manually loading a new plan either from the cursor cache or a SQL Tuning Set.

SQL Plan Baseline Attributes

A SQL plan baseline has several attributes that you can change in order to fine-tune the SQL Plan Management feature. The DBA_SQL_PLAN_BASELINES view provides detailed information about all the SQL plan baselines stored in the SMB. Here’s a query that shows how to find out key information about the SQL plan baselines in your database:

SQL> select sql_handle,plan_name,origin,enabled,accepted,fixed,autopurge
from dba_sql_plan_baselines;

SQL_HANDLE                               PLAN_NAME                                ORIGIN         ENABLED   ACC FIXED     AUTOPURGE
---------------------------------------- ---------------------------------------- -------------- --------- --- --------- ---------
SYS_SQL_0265b48f47be1bcf                 SQL_PLAN_04tdnjx3vw6yg56801109           MANUAL-LOAD    YES       YES NO        YES
SYS_SQL_03d675f2172c4dff                 SQL_PLAN_07pmpy8bksmgz6d032274           MANUAL-LOAD    YES       YES NO        YES
SYS_SQL_123f1ade69e70788                 SQL_PLAN_14gsuvtnyf1w841dc0d01           MANUAL-LOAD    YES       YES NO        YES
...............................................................

The following is a brief explanation of the key attributes of a SQL plan baseline:

  • SQL_HANDLE, SQL_TEXT, and PLAN_NAME identify the SQL statement.
  • The ORIGIN attribute denotes whether the plan was loaded manually (MANUAL-LOAD) and tuned by you (MANUAL-SQLTUNE), or if the database automatically captured the load (AUTO-CAPTURE) and tuned
  • it (AUTO-SQLTUNE).
  • enabled specifies whether the baseline plan is enabled by the optimizer for use.
  • accepted shows whether the plan has been verified and found not to lead to a performance regression.
  • fixed indicates whether this plan is one of the “fixed” cases. If any of the plans in a baseline are fixed, the database will consider the best plan among the fixed plans only. All other plans are ignored in preference to the fixed plans.
  • auto_purge shows whether the plan is automatically purged by the database.

Note that any plans that you load manually will always have the accepted status because they are deemed to be verified plans. You can also disable an accepted plan by removing the enabled setting through the ALTER_SQL_PLAN_BASELINE view. Here’s an example:

declare
  l_altered_plan pls_integer;
begin
  l_altered_plan := dbms_spm.alter_sql_plan_baseline(
    sql_handle  => 'SYS_SQL_0265b48f47be1bcf',
    plan_name   => 'SQL_PLAN_04tdnjx3vw6yg56801109',
    attribute_name  => 'enabled',
    attribute_value => 'NO');
  dbms_output.put_line('Plan altered: ' || l_altered_plan);
end;
/

A job must have the enabled and the accepted status in order for the optimizer to consider its use.

The SQL Management Base

The database stores all SPM related information, such as statement logs, plan histories, and SQL profiles as well as the SQL plan baselines, in a new component of the data dictionary called the SQL Management Base (SMB). The database stores the SMB in the SYSAUX tablespace. You must, therefore, ensure that the SYSAUX tablespace is online because SPM will be disabled if it can’t access the SYSAUX tablespace.  Configuring the SQL Management Base

You configure the SQL Management Base by setting values for two parameters, space_budget_percent and plan_retention_weeks. You can view the current values of these two parameters by querying the DBA_SQL_ MANAGEMENT_CONFIG view, as shown here:

SQL> select parameter_name,parameter_value
from dba_sql_management_config
PARAMETER_NAME                 PARAMETER_VALUE
------------------------------ ---------------
SPACE_BUDGET_PERCENT                        10
PLAN_RETENTION_WEEKS                        53

The space_budget_percent parameter determines the percentage of space the SMB can take up in the SYSAUX tablespace. You can select a value between 1 and 50 percent for this parameter. The default space limit is 10 percent of the size of the SYSAUX tablespace. The default unused plan retention period is one year and one week, which means a plan will be automatically purged if it has not been used for more than a year. When the space occupied by SQL management base exceeds the defined space budget limit, a weekly database alert is generated.
You can do one of the following to make the alert warnings go away:

  • Increase the size of the SYSAUX tablespace
  • Increase the SMB space limit
  • Purge outdated SQL plan baselines or SQL profiles to clear up space in the SMB

You can modify the value of the space_budget_percent parameter by executing the DBMS_SPM.CONFIGURE procedure, as shown here: 

SQL> exec dbms_spm.configure('space_budget_percent',20);

Purging Policies

A weekly purging task that’s part of the automated tasks that run during the maintenance windows takes care of removing older unused baselines, to conserve space in the SQL Management Base. By default, the database purges all SQL plans that the database hasn’t used in over a year (53 weeks, to be precise). You can, however, change this setting by adjusting the value of the plan_retention_weeks parameter to a value between 5 weeks and 523 weeks. The following example shows how to change the plan retention period to 2 years:

SQL> exec dbms_spm.configure('plan_retention_weeks',105);

drop all the sql plan baseline history

SET SERVEROUT ON;
DECLARE
v_plans_dropped pls_integer;
CURSOR C1 IS SELECT DISTINCT SQL_HANDLE FROM DBA_SQL_PLAN_BASELINES;
BEGIN
FOR I IN C1 LOOP
v_plans_dropped:=dbms_spm.drop_sql_plan_baseline(sql_handle=>I.SQL_HANDLE);
END LOOP;
END;
/

参考至:《McGraw.Hill.OCP.Oracle.Database.11g.New.Features.for.Administrators.Exam.Guide.Apr.2008》

              http://www.oracle-base.com/articles/11g/sql-plan-management-11gr1.php
              http://docs.oracle.com/cd/E11882_01/server.112/e41573/optplanmgmt.htm#PFGRF95123
              https://community.oracle.com/thread/1103054?start=0&tstart=0

本文原创,转载请注明出处、作者

如有错误,欢迎指正

邮箱:[email protected]

猜你喜欢

转载自czmmiao.iteye.com/blog/1956170