以下模拟如何在不改变sql文本的情况下使用sql profile来改变其执行计划,以期达到优化的目的。
sql profile分Manual ,AUTO两类,先介绍Manual方式的创建。
使用Manual的sql profile时,需要借助mos【215187.1】的脚本coe_xfr_sql_profile.sql 。
1,创建测试表。
-
SQL> select * from v$version;
-
-
BANNER
-
----------------------------------------------------------------
-
Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
-
PL/SQL Release 10.2.0.5.0 - Production
-
CORE 10.2.0.5.0 Production
-
TNS for IBM/AIX RISC System/6000: Version 10.2.0.5.0 - Productio
-
NLSRTL Version 10.2.0.5.0 - Production
-
-
-
SQL> create table tb_m as
-
2 select level c1,level+1 c2 from dual connect by level <101;
-
-
Table created
在表上建立索引,并收集统计信息。
-
SQL> create index ind_tb_m on tb_m(c1);
-
-
Index created
-
-
-
SQL> exec dbms_stats.gather_table_stats('YY','TB_M');
-
-
PL/SQL procedure successfully completed
执行以下sql(sql_1),执行计划是索引扫描。
-
SQL> explain plan for select * from tb_m a where c1=1;
-
-
Explained
-
-
SQL> select * from table(dbms_xplan.display());
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 3028611639
-
--------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
-
--------------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 6 | 2 (0)| 00
-
| 1 | TABLE ACCESS BY INDEX ROWID| TB_M | 1 | 6 | 2 (0)| 00
-
|* 2 | INDEX RANGE SCAN | IND_TB_M | 1 | | 1 (0)| 00
-
--------------------------------------------------------------------------------
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
2 - access(\"C1\"=1)
-
-
14 rows selected
如果现在不想让sql_1走索引,如何用sql profile改写它。
首先将sql_1加hint提示改写成sql_2。
sql_2:
select/*+no_index(a) */ * from tb_m a where c1=1;
-
SQL> explain plan for select/*+no_index(a) */ * from tb_m a where c1=1;
-
-
Explained
-
-
SQL> select * from table(dbms_xplan.display());
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 4109591867
-
--------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-
--------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 6 | 3 (0)| 00:00:01 |
-
|* 1 | TABLE ACCESS FULL| TB_M | 1 | 6 | 3 (0)| 00:00:01 |
-
--------------------------------------------------------------------------
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
1 - filter(\"C1\"=1)
-
-
13 rows selected
分别找到其sql_id和对应的plan_hash_value。
sql_1 : fzruqwqvu81dd
sql_2 : f12uvb7b6j270
-
SQL> select sql_text,sql_id,version_count from v$sqlarea where sql_text like '%where c1=1%';
-
-
SQL_TEXT SQL_ID VERSION_COUNT
-
-------------------------------------------------------------------------------- ------------------------------ -------------
-
select * from tb_m a where c1=1 fzruqwqvu81dd 1
-
select/*+no_index(a) */ * from tb_m a where c1=1 f12uvb7b6j270 1
-
-
-
SQL> select sql_id,plan_hash_value from v$sql where sql_id in ('fzruqwqvu81dd','f12uvb7b6j270');
-
-
SQL_ID PLAN_HASH_VALUE
-
------------------------------ ------------------------------
-
fzruqwqvu81dd 3028611639
-
f12uvb7b6j270 4109591867
使用脚本coe_xfr_sql_profile.sql生成sql_1的manual sqlprofile ;
-
SQL>@'d:\coe_xfr_sql_profile.sql' fzruqwqvu81dd 3028611639
-
-
Parameter 1:
-
SQL_ID (required)
-
-
-
-
-
-
-
PLAN_HASH_VALUE AVG_ET_SECS
-
--------------- -----------
-
3028611639 .001
-
-
-
Parameter 2:
-
PLAN_HASH_VALUE (required)
-
-
-
-
-
Values passed to coe_xfr_sql_profile:
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
SQL_ID : \"fzruqwqvu81dd\"
-
PLAN_HASH_VALUE: \"3028611639\"
-
-
-
SQL>BEGIN
-
2 IF :sql_text IS NULL THEN
-
3 RAISE_APPLICATION_ERROR(-20100, \'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).\');
-
4 END IF;
-
5 END;
-
6 /
-
SQL>SET TERM OFF;
-
SQL>BEGIN
-
2 IF :other_xml IS NULL THEN
-
3 RAISE_APPLICATION_ERROR(-20101, \'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).\');
-
4 END IF;
-
5 END;
-
6 /
-
SQL>SET TERM OFF;
-
-
-
Execute coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql
-
on TARGET system in order to create a custom SQL Profile
-
with plan 3028611639 linked to adjusted sql_text.
-
-
-
-
-
COE_XFR_SQL_PROFILE completed.
使用脚本coe_xfr_sql_profile.sql生成sql_2的manual sqlprofile ;
-
SQL>@'d:\coe_xfr_sql_profile.sql' f12uvb7b6j270 4109591867
-
-
-
Parameter 1:
-
SQL_ID (required)
-
-
-
-
-
-
-
PLAN_HASH_VALUE AVG_ET_SECS
-
--------------- -----------
-
4109591867 .002
-
-
-
Parameter 2:
-
PLAN_HASH_VALUE (required)
-
-
-
-
-
Values passed to coe_xfr_sql_profile:
-
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
-
SQL_ID : \"f12uvb7b6j270\"
-
PLAN_HASH_VALUE: \"4109591867\"
-
-
-
SQL>BEGIN
-
2 IF :sql_text IS NULL THEN
-
3 RAISE_APPLICATION_ERROR(-20100, \'SQL_TEXT for SQL_ID &&sql_id. was not found in memory (gv$sqltext_with_newlines) or AWR (dba_hist_sqltext).\');
-
4 END IF;
-
5 END;
-
6 /
-
SQL>SET TERM OFF;
-
SQL>BEGIN
-
2 IF :other_xml IS NULL THEN
-
3 RAISE_APPLICATION_ERROR(-20101, \'PLAN for SQL_ID &&sql_id. and PHV &&plan_hash_value. was not found in memory (gv$sql_plan) or AWR (dba_hist_sql_plan).\');
-
4 END IF;
-
5 END;
-
6 /
-
SQL>SET TERM OFF;
-
-
-
Execute coe_xfr_sql_profile_f12uvb7b6j270_4109591867.sql
-
on TARGET system in order to create a custom SQL Profile
-
with plan 4109591867 linked to adjusted sql_text.
-
-
-
-
-
COE_XFR_SQL_PROFILE completed.
会生成2个.sql文件,sql_1对应的是coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql;
sql_2对应的是coe_xfr_sql_profile_f12uvb7b6j270_4109591867.sql;
打开.sql文件会发现如下内容:
-
h := SYS.SQLPROF_ATTR(
-
q\'[BEGIN_OUTLINE_DATA]\',
-
q\'[IGNORE_OPTIM_EMBEDDED_HINTS]\',
-
q\'[OPTIMIZER_FEATURES_ENABLE(\'10.2.0.5\')]\',
-
q\'[ALL_ROWS]\',
-
q\'[OUTLINE_LEAF(@\"SEL$1\")]\',
-
q\'[FULL(@\"SEL$1\" \"A\"@\"SEL$1\")]\',
-
q\'[END_OUTLINE_DATA]\');
将sql_2(coe_xfr_sql_profile_f12uvb7b6j270_4109591867.sql)中的以上内容替换到sql_1(coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql)中。
同时执行coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql;
SQL> @'d:\coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql';
-
SQL> @'d:\coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql';
-
SQL>REM
-
SQL>REM $Header: 215187.1 coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql 11.4.3.5 2014/12/11 carlos.sierra $
-
SQL>REM
-
SQL>REM Copyright (c) 2000-2011, Oracle Corporation. All rights reserved.
-
SQL>REM
-
SQL>REM AUTHOR
-
SQL>REM carlos.sierra@oracle.com
-
SQL>REM
-
SQL>REM SCRIPT
-
SQL>REM coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql
-
SQL>REM
-
SQL>REM DESCRIPTION
-
SQL>REM This script is generated by coe_xfr_sql_profile.sql
-
SQL>REM It contains the SQL*Plus commands to create a custom
-
SQL>REM SQL Profile for SQL_ID fzruqwqvu81dd based on plan hash
-
SQL>REM value 3028611639.
-
SQL>REM The custom SQL Profile to be created by this script
-
SQL>REM will affect plans for SQL commands with signature
-
SQL>REM matching the one for SQL Text below.
-
SQL>REM Review SQL Text and adjust accordingly.
-
SQL>REM
-
SQL>REM PARAMETERS
-
SQL>REM None.
-
SQL>REM
-
SQL>REM EXAMPLE
-
SQL>REM SQL> START coe_xfr_sql_profile_fzruqwqvu81dd_3028611639.sql;
-
SQL>REM
-
SQL>REM NOTES
-
SQL>REM 1. Should be run as SYSTEM or SYSDBA.
-
SQL>REM 2. User must have CREATE ANY SQL PROFILE privilege.
-
SQL>REM 3. SOURCE and TARGET systems can be the same or similar.
-
SQL>REM 4. To drop this custom SQL Profile after it has been created:
-
SQL>REM EXEC DBMS_SQLTUNE.DROP_SQL_PROFILE(\'coe_fzruqwqvu81dd_3028611639\');
-
SQL>REM 5. Be aware that using DBMS_SQLTUNE requires a license
-
SQL>REM for the Oracle Tuning Pack.
-
SQL>REM
-
SQL>WHENEVER SQLERROR EXIT SQL.SQLCODE;
-
SQL>REM
-
SQL>VAR signature NUMBER;
-
SQL>REM
-
SQL>DECLARE
-
2 sql_txt CLOB;
-
3 h SYS.SQLPROF_ATTR;
-
4 BEGIN
-
5 sql_txt := q\'[
-
6 select * from tb_m a where c1=1
-
7 ]\';
-
8 h := SYS.SQLPROF_ATTR(
-
9 q\'[BEGIN_OUTLINE_DATA]\',
-
10 q\'[IGNORE_OPTIM_EMBEDDED_HINTS]\',
-
11 q\'[OPTIMIZER_FEATURES_ENABLE(\'10.2.0.5\')]\',
-
12 q\'[ALL_ROWS]\',
-
13 q\'[OUTLINE_LEAF(@\"SEL$1\")]\',
-
14 q\'[FULL(@\"SEL$1\" \"A\"@\"SEL$1\")]\',
-
15 q\'[END_OUTLINE_DATA]\');
-
16 :signature := DBMS_SQLTUNE.SQLTEXT_TO_SIGNATURE(sql_txt);
-
17 DBMS_SQLTUNE.IMPORT_SQL_PROFILE (
-
18 sql_text => sql_txt,
-
19 profile => h,
-
20 name => \'coe_fzruqwqvu81dd_3028611639\',
-
21 description => \'coe fzruqwqvu81dd 3028611639 \'||:signature||\'\',
-
22 category => \'DEFAULT\',
-
23 validate => TRUE,
-
24 replace => TRUE,
-
25 force_match => FALSE /* TRUE:FORCE (match even when different literals in SQL). FALSE:EXACT (similar to CURSOR_SHARING) */ );
-
26 END;
-
27 /
-
-
-
PL/SQL 过程已成功完成。
-
-
-
SQL>WHENEVER SQLERROR CONTINUE
-
SQL>SET ECHO OFF;
-
-
-
SIGNATURE
-
---------------------
-
16498969119777112484
-
-
-
-
-
... manual custom SQL Profile has been created
-
-
-
-
-
COE_XFR_SQL_PROFILE_fzruqwqvu81dd_3028611639 completed
接下来再执行一下sql_1,发现其已经由索引扫描变成了全表扫描。
-
SQL> explain plan for select * from tb_m a where c1=1;
-
-
Explained
-
-
SQL> select * from table(dbms_xplan.display());
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 4109591867
-
--------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
-
--------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 6 | 3 (0)| 00:00:01 |
-
|* 1 | TABLE ACCESS FULL| TB_M | 1 | 6 | 3 (0)| 00:00:01 |
-
--------------------------------------------------------------------------
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
1 - filter(\"C1\"=1)
-
Note
-
-----
-
- SQL profile \"coe_fzruqwqvu81dd_3028611639\" used for this statement
-
-
17 rows selected
如果将变量值修改一下,执行计划会如何呢?
发现其又变成了索引扫描。
-
SQL> explain plan for select * from tb_m a where c1=2;
-
-
Explained
-
-
SQL> select * from table(dbms_xplan.display());
-
-
PLAN_TABLE_OUTPUT
-
--------------------------------------------------------------------------------
-
Plan hash value: 3028611639
-
--------------------------------------------------------------------------------
-
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Ti
-
--------------------------------------------------------------------------------
-
| 0 | SELECT STATEMENT | | 1 | 6 | 2 (0)| 00
-
| 1 | TABLE ACCESS BY INDEX ROWID| TB_M | 1 | 6 | 2 (0)| 00
-
|* 2 | INDEX RANGE SCAN | IND_TB_M | 1 | | 1 (0)| 00
-
--------------------------------------------------------------------------------
-
Predicate Information (identified by operation id):
-
---------------------------------------------------
-
2 - access(\"C1\"=2)
-
-
14 rows selected
针对此情况,修改文件coe_fzruqwqvu81dd_3028611639.sql的force_match参数即可。
将force_match 由FALSE 修改为 TRUE;
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/30049665/viewspace-1364846/
,如需转载,请注明出处,否则将追究法律责任。