在遭遇执行计划不稳定或者执行计划错误的情况下,通过baseline来固定SQL执行计划以确保执行计划稳定性、提高性能。baseline是oracle 11G提供的稳固sql执行计划的功能,是spm功能的一部分。
步骤如下:
-
SQL> set linesize 1000
-
SQL> col index_name for a40
-
SQL> col COLUMN_NAME for a20
-
SQL> select index_name,COLUMN_NAME from dba_ind_columns where table_name='TEST_PART' and table_owner='TEST_DBA';
-
-
INDEX_NAME COLUMN_NAME
-
---------------------------------------- --------------------
-
IND_PART_DT DT
-
-
SQL>
-
此表由索引,可以测试走做引以及走全表扫描
-
SQL> set autotrace on explain
-
SQL> set pagesize 300
-
SQL> set linesize 300
-
SQL> var name1 varchar2(10);
-
SQL> var name2 varchar2(100);
-
SQL> var name1 varchar2(100);
-
SQL> exec :name1 :='2012-09-21 8:05:55';
-
-
PL/SQL procedure successfully completed.
-
-
SQL> exec :name2 :='2012-09-21 8:06:05';
-
-
PL/SQL procedure successfully completed.
-
SQL> select * from TEST_DBA.TEST_PART where dt>=to_date(:name1,'yyyy-mm-dd hh24:mi:ss') and
-
2 dt<to_date(:name2,'yyyy-mm-dd hh24:mi:ss') ;
-
-
ID STR DT
-
---------- ---------- ---------
-
29155 aaaaaaaaa 21-SEP-12
-
29156 aaaaaaaaa 21-SEP-12
-
29157 aaaaaaaaa 21-SEP-12
-
29158 aaaaaaaaa 21-SEP-12
-
29159 aaaaaaaaa 21-SEP-12
-
29160 aaaaaaaaa 21-SEP-12
-
29161 aaaaaaaaa 21-SEP-12
-
29162 aaaaaaaaa 21-SEP-12
-
29163 aaaaaaaaa 21-SEP-12
-
29164 aaaaaaaaa 21-SEP-12
-
-
10 rows selected.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
Plan hash value: 2229598636
-
-
-------------------------------------------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-
-------------------------------------------------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 250 | 5750 | 5 (0)| 00:00:01 | | |
-
|* 1 | FILTER | | | | | | | |
-
| 2 | PARTITION RANGE ITERATOR | | 250 | 5750 | 5 (0)| 00:00:01 | KEY | KEY |
-
| 3 | TABLE ACCESS BY LOCAL INDEX ROWID| TEST_PART | 250 | 5750 | 5 (0)| 00:00:01 | KEY | KEY |
-
|* 4 | INDEX RANGE SCAN | IND_PART_DT | 450 | | 3 (0)| 00:00:01 | KEY | KEY |
-
-------------------------------------------------------------------------------------------------------------------
-
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
-
1 - filter(TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss')<TO_DATE(:NAME2,'yyyy-mm-dd hh24:mi:ss'))
-
4 - access("DT">=TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss') AND "DT"<TO_DATE(:NAME2,'yyyy-mm-dd
-
hh24:mi:ss'))
-
以上生成了索引的执行sql
-
-
SQL> select /*+FULL(TEST_PART)*/ * from TEST_DBA.TEST_PART where dt>=to_date(:name1,'yyyy-mm-dd hh24:mi:ss') and
-
2 dt<to_date(:name2,'yyyy-mm-dd hh24:mi:ss') ;
-
-
ID STR DT
-
---------- ---------- ---------
-
29155 aaaaaaaaa 21-SEP-12
-
29156 aaaaaaaaa 21-SEP-12
-
29157 aaaaaaaaa 21-SEP-12
-
29158 aaaaaaaaa 21-SEP-12
-
29159 aaaaaaaaa 21-SEP-12
-
29160 aaaaaaaaa 21-SEP-12
-
29161 aaaaaaaaa 21-SEP-12
-
29162 aaaaaaaaa 21-SEP-12
-
29163 aaaaaaaaa 21-SEP-12
-
29164 aaaaaaaaa 21-SEP-12
-
-
10 rows selected.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
Plan hash value: 1956636844
-
-
-------------------------------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-
-------------------------------------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 250 | 5750 | 161 (3)| 00:00:02 | | |
-
|* 1 | FILTER | | | | | | | |
-
| 2 | PARTITION RANGE ITERATOR| | 250 | 5750 | 161 (3)| 00:00:02 | KEY | KEY |
-
|* 3 | TABLE ACCESS FULL | TEST_PART | 250 | 5750 | 161 (3)| 00:00:02 | KEY | KEY |
-
-------------------------------------------------------------------------------------------------------
-
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
-
1 - filter(TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss')<TO_DATE(:NAME2,'yyyy-mm-dd hh24:mi:ss'))
-
3 - filter("DT">=TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss') AND
-
"DT"<TO_DATE(:NAME2,'yyyy-mm-dd hh24:mi:ss'))
-
以上是走全表扫描的执行计划
-
现在要将该语句全部变为走全表扫描,也就是用全表扫描的执行计划来绑定该语句
-
SQL> select sql_id from v$sql_plan where plan_hash_value=2229598636;
-
-
SQL_ID
-
-------------
-
day4zwzuhxjnd
-
day4zwzuhxjnd
-
day4zwzuhxjnd
-
day4zwzuhxjnd
-
day4zwzuhxjnd
-
-
SQL> select sql_id from v$sql_plan where plan_hash_value=1956636844;
-
-
SQL_ID
-
-------------
-
fzs1wktabj9ny
-
fzs1wktabj9ny
-
fzs1wktabj9ny
-
fzs1wktabj9ny
-
进行绑定
-
SQL> declare
-
2 m_clob clob;
-
3 begin
-
4 select sql_fulltext
-
5 into m_clob
-
6 from v$sql
-
7 where sql_id = 'day4zwzuhxjnd'
-
8 and child_number = 0;
-
9 dbms_output.put_line(m_clob);
-
10 dbms_output.put_line(dbms_spm.load_plans_from_cursor_cache(
-
11 sql_id => 'fzs1wktabj9ny',
-
12 plan_hash_value => 1956636844,
-
13 sql_text => m_clob,
-
14 fixed => 'YES',
-
15 enabled => 'YES'));
-
16 end;
-
17 /
-
PL/SQL procedure successfully completed.
-
验证
-
SQL> select * from TEST_DBA.TEST_PART where dt>=to_date(:name1,'yyyy-mm-dd hh24:mi:ss') and
-
2 dt<to_date(:name2,'yyyy-mm-dd hh24:mi:ss') ;
-
-
ID STR DT
-
---------- ---------- ---------
-
29155 aaaaaaaaa 21-SEP-12
-
29156 aaaaaaaaa 21-SEP-12
-
29157 aaaaaaaaa 21-SEP-12
-
29158 aaaaaaaaa 21-SEP-12
-
29159 aaaaaaaaa 21-SEP-12
-
29160 aaaaaaaaa 21-SEP-12
-
29161 aaaaaaaaa 21-SEP-12
-
29162 aaaaaaaaa 21-SEP-12
-
29163 aaaaaaaaa 21-SEP-12
-
29164 aaaaaaaaa 21-SEP-12
-
-
10 rows selected.
-
-
-
Execution Plan
-
----------------------------------------------------------
-
Plan hash value: 1956636844
-
-
-------------------------------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time | Pstart| Pstop |
-
-------------------------------------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 250 | 5750 | 161 (3)| 00:00:02 | | |
-
|* 1 | FILTER | | | | | | | |
-
| 2 | PARTITION RANGE ITERATOR| | 250 | 5750 | 161 (3)| 00:00:02 | KEY | KEY |
-
|* 3 | TABLE ACCESS FULL | TEST_PART | 250 | 5750 | 161 (3)| 00:00:02 | KEY | KEY |
-
-------------------------------------------------------------------------------------------------------
-
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
-
1 - filter(TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss')<TO_DATE(:NAME2,'yyyy-mm-dd hh24:mi:ss'))
-
3 - filter("DT">=TO_DATE(:NAME1,'yyyy-mm-dd hh24:mi:ss') AND
-
"DT"<TO_DATE(:NAME2,'yyyy-mm-dd hh24:mi:ss'))
-
-
Note
-
-----
-
- SQL plan baseline "SQL_PLAN_c28fvkn3sbtbg70e51298" used for this statement
-
-
SQL>
-
-
查看生成的sql baseline信息
-
SQL> select signature,sql_handle,plan_name,origin,enabled,accepted,fixed,autopurge
-
2 from dba_sql_plan_baselines where sql_text like '%select * from TEST_DBA.TEST_PART%';
-
-
SIGNATURE SQL_HANDLE PLAN_NAME ORIGIN ENA ACC FIX AUT
-
---------- ------------------------------ ------------------------------ -------------- --- --- --- ---
-
1.3917E+19 SQL_c121db950785e56f SQL_PLAN_c28fvkn3sbtbg70e51298 MANUAL-LOAD YES YES YES YES
-
-
SQL>
-
如果不想要这个绑定计划了,则可以删除它
-
declare
-
l_pls number;
-
begin
-
l_pls := DBMS_SPM.DROP_SQL_PLAN_BASELINE(
-
sql_handle => 'SQL_c121db950785e56f',
-
plan_name => 'SQL_PLAN_c28fvkn3sbtbg70e51298'
-
);
-
end;
对于dbms_spm.load_plans_from_cursor_cache的说明
既然是from cursor的话那么要保证在执行过程中sql还是在内存里的不能被刷出去
declare
m_clob clob;
begin
select sql_fulltext
into m_clob
from v$sql
where sql_id = 'day4zwzuhxjnd'————–原始sql的 sql_id
and child_number = 0;—————–为了让sql只返回一行,也可以rownum=1代替
dbms_output.put_line(m_clob);
dbms_output.put_line(dbms_spm.load_plans_from_cursor_cache(
sql_id => 'fzs1wktabj9ny',————HINT SQL_ID
plan_hash_value => 1956636844,——————-HINT PLAN_HASH_VALUE
sql_text => m_clob,————————-原始SQL文本
fixed => 'YES', ———————禁止演化baseline
enabled => 'YES'));------生效
end;
出处:
http://blog.csdn.net/aaaaaaaa2000/article/details/9086111
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/29119536/viewspace-1572204/
,如需转载,请注明出处,否则将追究法律责任。