以下模拟如何在不改变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_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.
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博客 ” ,链接:http://blog.itpub.net/30049665/viewspace-1364846/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/30049665/viewspace-1364846/