您的位置:首页 > 数据库

使用SQL Profile及SQL Tuning Advisor固定运行计划

2017-06-20 21:54 423 查看
SQL Profile就是为某一SQL语句提供除了系统统计信息、对象(表和索引等)统计信息之外的其它信息。比方执行环境、额外的更准确的统计信息。以帮助优化器为SQL语句选择更适合的执行计划。

SQL Profiles可以说是Outlines的进化。Outlines可以实现的功能SQL Profiles也全然可以实现,而SQL Profiles具有Outlines不具备的优化,最重要的有二点:

SQL Profiles更easy生成、更改和控制。

SQL Profiles在对SQL语句的支持上做得更好。也就是适用范围更广。

使用SQL Profiles两个目的:

锁定或者说是稳定运行计划。

在不能改动应用中的SQL的情况下使SQL语句按指定的执行计划执行。

參考老熊的博客,链接:http://www.laoxiong.net/sql-profiles-partii.html http://www.laoxiong.net/sql-profiles-part.html http://blog.sina.com.cn/s/blog_5037eacb01011mgu.htm

1.实验环境构造语句:

create table bys.t1 as select * from dba_objects;

create index bys.t1_idx on t1(object_id);

exec dbms_stats.gather_table_stats('bys','t1',cascade=>true,degree=>4);

set autotrace trace;

select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;

select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;

set autotrace off;

explain plan for select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;

col sql_text for a100

SELECT SQL_ID,SQL_TEXT FROM V$SQL WHERE SQL_TEXT LIKE '%a.*,b.owner from t1 a,t1 b%';

####2t5xqt4d1dsaw

10g開始,v$sql_plan中就包含了SQL语句OUTLINE数据,也就是稳定运行计划的Hints。例如以下:

set pagesize 1000

SQL> select * from table(dbms_xplan.display_cursor('2t5xqt4d1dsaw',null,'outline'));

PLAN_TABLE_OUTPUT

---------------------------------------------------------------------------------------------------------------

SQL_ID 2t5xqt4d1dsaw, child number 0

-------------------------------------

select /*+ use_nl(a b) index(t2) */ a.*,b.owner from t1 a,t1 b where

a.object_name like '%T1%' and a.object_id=b.object_id

Plan hash value: 190596302

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | | | 979 (100)| |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 9 | 2 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 471 | 43803 | 979 (1)| 00:00:12 |

|* 3 | TABLE ACCESS FULL | T1 | 471 | 39564 | 36 (0)| 00:00:01 |

|* 4 | INDEX RANGE SCAN | T1_IDX | 1 | | 1 (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Outline Data ----------这一部分: /*+ */ 之间的就是所需的数据了

-------------

/*+

BEGIN_OUTLINE_DATA

IGNORE_OPTIM_EMBEDDED_HINTS

OPTIMIZER_FEATURES_ENABLE('10.2.0.1')

ALL_ROWS

OUTLINE_LEAF(@"SEL$1")

FULL(@"SEL$1" "A"@"SEL$1")

INDEX(@"SEL$1" "B"@"SEL$1" ("T1"."OBJECT_ID"))

LEADING(@"SEL$1" "A"@"SEL$1" "B"@"SEL$1")

USE_NL(@"SEL$1" "B"@"SEL$1")

END_OUTLINE_DATA

*/

PLAN_TABLE_OUTPUT

-----------------------------------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

3 - filter("A"."OBJECT_NAME" LIKE '%T1%')

4 - access("A"."OBJECT_ID"="B"."OBJECT_ID")

###############################################################################

2.開始创建并应用SQL Profile

使用未加HINT的SQL语句,并指定SQL_PROFILE名字:SQLPROFILE_T1

注意事项:两个引號---如('10.2.0.1')要写成(''10.2.0.1'')--'%T1%'写成''%T1%''

SQL语句结尾的;不要写上,绑定变量值是'1'时,要输入''1''

declare

v_hints sys.sqlprof_attr;

begin

v_hints:=sys.sqlprof_attr(

'BEGIN_OUTLINE_DATA',

'IGNORE_OPTIM_EMBEDDED_HINTS',

'OPTIMIZER_FEATURES_ENABLE(''10.2.0.1'')',

'ALL_ROWS',

'OUTLINE_LEAF(@"SEL$1")',

'FULL(@"SEL$1" "A"@"SEL$1")',

'INDEX(@"SEL$1" "B"@"SEL$1" ("T1"."OBJECT_ID"))',

'LEADING(@"SEL$1" "A"@"SEL$1" "B"@"SEL$1")',

'USE_NL(@"SEL$1" "B"@"SEL$1")',

'END_OUTLINE_DATA');

dbms_sqltune.import_sql_profile(

'select a.*,b.owner from t1 a,t1 b where a.object_name like ''%T1%'' and a.object_id=b.object_id',

v_hints,'SQLPROFILE_T1',

force_match=>true,replace=>true);

end;

/

删除语句:

exec dbms_sqltune.drop_sql_profile(name =>'SQLPROFILE_T1' );

######

3.验证SQL语句是否使用上一步创建的SQL_PROFILE:

SQL> set autotrace trace;

SQL> select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;

23 rows selected.

Execution Plan

----------------------------------------------------------

Plan hash value: 190596302

--------------------------------------------------------------------------------------

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |

--------------------------------------------------------------------------------------

| 0 | SELECT STATEMENT | | 471 | 43803 | 979 (1)| 00:00:12 |

| 1 | TABLE ACCESS BY INDEX ROWID| T1 | 1 | 9 | 2 (0)| 00:00:01 |

| 2 | NESTED LOOPS | | 471 | 43803 | 979 (1)| 00:00:12 |

|* 3 | TABLE ACCESS FULL | T1 | 471 | 39564 | 36 (0)| 00:00:01 |

|* 4 | INDEX RANGE SCAN | T1_IDX | 1 | | 1 (0)| 00:00:01 |

--------------------------------------------------------------------------------------

Predicate Information (identified by operation id):

---------------------------------------------------

3 - filter("A"."OBJECT_NAME" LIKE '%T1%')

4 - access("A"."OBJECT_ID"="B"."OBJECT_ID")

Note

-----

- SQL profile "SQLPROFILE_T1" used for this statement

Statistics

----------------------------------------------------------

1 recursive calls

0 db block gets

163 consistent gets

0 physical reads

0 redo size

2609 bytes sent via SQL*Net to client

392 bytes received via SQL*Net from client

3 SQL*Net roundtrips to/from client

0 sorts (memory)

0 sorts (disk)

23 rows processed 0 sorts (disk)

#####################################################################

使用Oracle的SQL Tuning Advisor固定运行计划--SQL_ID

----通过sql_id的方式 sql_id => 'a2h6pzvqncfvg',--想调优的sql_id

show serveroutput

set serveroutput on;

DECLARE

a_tuning_task VARCHAR2(30);

BEGIN

a_tuning_task := dbms_sqltune.create_tuning_task(sql_id => 'a2h6pzvqncfvg',task_name => 'tuning_test');

dbms_sqltune.execute_tuning_task(a_tuning_task);

END;

/

set long 1000

SELECT dbms_sqltune.report_tuning_task('tuning_test') FROM dual;

这里的输出中的sql_id是从v$sql查出,相应的是没有加hint的SQL。

假设SQL Tuning Advisor找到了理想的运行计划,下一步就是:Accept SQL Profile。接受这个SQL Profile。

## execute dbms_sqltune.accept_sql_profile(task_name =>'tuning_test' ,replace => TRUE,force_match=>true);

完毕后验证语句:

set autotrace trace;

select a.*,b.owner from t1 a,t1 b where a.object_name like '%T1%' and a.object_id=b.object_id;

set autotrace off;

删除SQL语句:

exec dbms_sqltune.drop_tuning_task('tuning_test');

假设未找到理想的运行计划,则參考下一个方法。

##################################################################

使用Oracle的SQL Tuning Advisor固定运行计划--使用SQL_TEXT。參考下面:

DECLARE

my_task_name VARCHAR2 (30);

my_sqltext CLOB;

BEGIN

my_sqltext := 'select * from test where OBJECT_ID=15'; --想调优的sql

my_task_name := dbms_sqltune.create_tuning_task (sql_text=> my_sqltext,

--bind_list => 'UNDO$',

--user_name => 'SONG',

--scope => 'COMPREHENSIVE',

--time_limit => 60,

task_name => 'sql_tuning_test'

--description => 'Tuning Task'

);

END;

/

exec dbms_sqltune.execute_tuning_task('sql_tuning_test'); --运行调优的任务

SELECT STATUS FROM USER_ADVISOR_TASKS WHERE task_name = 'sql_tuning_test'; --查看调优作业的状态

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('sql_tuning_test') FROM DUAL;--查看调优的建议

exec dbms_sqltune.drop_tuning_task('sql_tuning_test');--删除任务
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: