使用hint优化Oracle的运行计划 以及 SQL Tune Advisor的使用

背景:

某表忽然出现查询很缓慢的情况。cost 100+ 秒以上;严重影响生产。

原SQL:

explain plan for
select * from (
select ID id,RET_NO retNo, FROM_SYS fromSy, TO_SYS toSys, COMMAND_CODE commandCode, COMMAND, STATUS,
EXT_CODE, ORIGN_CODE orignCode,error_message errorMessage, RE_F, RET_MSG retMsg
from interface_table where ((command_code in(‘AASSS‘)
			and  status in(‘F‘,‘E‘) and (re_f = ‘N‘) and FROM_SYS = ‘MEE‘)
			or (COMMAND_CODE in(‘XXXX‘,‘XXXX9‘) and FROM_SYS = ‘EXT‘ and RE_F = ‘N‘)
			) and MOD(id, 1) = 0  order by id) where rownum <= 100  ;

查看其运行计划:

SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY(‘PLAN_TABLE‘));
Plan hash value: 1871549687
?
----------------------------------------------------------------------------------------------------
| Id? | Operation???????????????????? | Name?????????????? | Rows? | Bytes | Cost (%CPU)| Time???? |
----------------------------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT????????????? |??????????????????? |??? 99 |?? 382K|?? 637?? (1)| 00:00:08 |
|*? 1 |? COUNT STOPKEY??????????????? |??????????????????? |?????? |?????? |??????????? |????????? |
|?? 2 |?? VIEW??????????????????????? |??????????????????? |?? 100 |?? 386K|?? 637?? (1)| 00:00:08 |
|*? 3 |??? TABLE ACCESS BY INDEX ROWID| INTERFACE_TABLE??? |?? 355 | 55735 |?? 637?? (1)| 00:00:08 |
|*? 4 |???? INDEX FULL SCAN?????????? | PK_INTERFACE_TABLE |? 1439 |?????? |?? 280?? (2)| 00:00:04 |
----------------------------------------------------------------------------------------------------

优化后的SQL:

explain plan for
select * from (
select /*+ index(INT_TABLE IX_INT_TABLE_2)*/ ID id,RET_NO retNo, FROM_SYS fromSy, TO_SYS toSys, COMMAND_CODE commandCode, COMMAND, STATUS,
EXT_CODE, ORIGN_CODE orignCode,error_message errorMessage, RE_F, RET_MSG retMsg
from interface_table where ((command_code in(‘AASSS‘)
			and  status in(‘F‘,‘E‘) and (re_f = ‘N‘) and FROM_SYS = ‘MEE‘)
			or (COMMAND_CODE in(‘XXXX‘,‘XXXX9‘) and FROM_SYS = ‘EXT‘ and RE_F = ‘N‘)
			) and MOD(id, 1) = 0 order by id) where rownum <= 100  ;

查看其运行计划:

SELECT plan_table_output FROM TABLE(DBMS_XPLAN.DISPLAY(‘PLAN_TABLE‘));
Plan hash value: 3625182869
?
--------------------------------------------------------------------------------------------------------
| Id? | Operation?????????????????????? | Name???????????????? | Rows? | Bytes | Cost (%CPU)| Time???? |
--------------------------------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT??????????????? |????????????????????? |??? 99 |?? 382K| 19105?? (1)| 00:03:50 |
|*? 1 |? COUNT STOPKEY????????????????? |????????????????????? |?????? |?????? |??????????? |????????? |
|?? 2 |?? VIEW????????????????????????? |????????????????????? |?? 356 |? 1376K| 19105?? (1)| 00:03:50 |
|*? 3 |??? SORT ORDER BY STOPKEY??????? |????????????????????? |?? 356 | 55892 | 19105?? (1)| 00:03:50 |
|?? 4 |???? CONCATENATION?????????????? |????????????????????? |?????? |?????? |??????????? |????????? |
|*? 5 |????? TABLE ACCESS BY INDEX ROWID| INTERFACE_TABLE????? |??? 69 | 10833 |? 9552?? (1)| 00:01:55 |
|*? 6 |?????? INDEX RANGE SCAN????????? | IX_INTERFACE_TABLE_2 | 77145 |?????? |??? 99?? (0)| 00:00:02 |
|*? 7 |????? TABLE ACCESS BY INDEX ROWID| INTERFACE_TABLE????? |?? 287 | 45059 |? 9552?? (1)| 00:01:55 |
|*? 8 |?????? INDEX RANGE SCAN????????? | IX_INTERFACE_TABLE_2 | 77145 |?????? |??? 99?? (0)| 00:00:02 |
--------------------------------------------------------------------------------------------------------

比較:

查看运行计划。原来是使用 full scan - 当数据量大时很慢。优化后oracle优先走range scan,hint 的 index 是未处理标识字段的索引,正常情况下这个数据集合相对较小--------所以能够达到优化目的。

详细情况详细分析,我们必需要看实际的表存的业务数据。分析其业务关系找到最小业务集合。后者要看懂运行计划,依据rows, bytes, cost, time 找到最优项目。这个分析顺序不能倒置。

问题:为何使用 rownum 后,oracle运行计划会走full scan?

转:怎样看懂运行计划:http://jadethao.iteye.com/blog/1613943

====? section2 ====

http://blog.chinaunix.net/uid-77311-id-3233190.html

环境:

OS:Red Hat Linux As 5

DB:10.2.0.4

?

Oracle通过STA给出某个SQL运行建议,以下通过一个測试检查Oracle给出的优化建议是否正确.

?

1.建表并生成測试数据

SQL> create table tb_test(id number not null,name varchar2(30));

Table created.

SQL> create index idx_tb_test on tb_test(id);

Index created.

SQL> declare
begin
? for i in 1 .. 100000 loop
??? insert into tb_test values (i, ‘test‘);
??? commit;
? end loop;
end;
/

?

2.分析表

begin
? dbms_stats.gather_table_stats(ownname => ‘SCOTT‘, tabname => ‘TB_TEST‘);
end;

3.编造一个运行计划不正确的SQL

select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1

我们知道在ID列上有索引,这个SQL走索引是正确的运行计划,但这里强制oracle走全表扫描,然后通过STA,看oracle给出的运行计划是否正确.

4.创建TUNING_TASK并运行

declare
? l_task_name varchar2(30);
? l_sql?????? clob;
begin
? l_sql?????? := ‘select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1‘;
? l_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text??? => l_sql,
???????????????????????????????????????????????? user_name?? => ‘SCOTT‘,
???????????????????????????????????????????????? scope?????? => ‘COMPREHENSIVE‘,
???????????????????????????????????????????????? time_limit? => 60,
???????????????????????????????????????????????? task_name?? => ‘task_name01‘,
???????????????????????????????????????????????? description => null);
dbms_sqltune.Execute_tuning_task(task_name => ‘task_name01‘);
end;

5.查看oracle给出的优化建议

SQL> set serveroutput on;
SQL> set long 999999999;
SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(‘task_name01‘) FROM DUAL;

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name????????????????? : task_name01
Tuning Task Owner???????????????? : SYS
Scope???????????????????????????? : COMPREHENSIVE
Time Limit(seconds)?????????????? : 60
Completion Status???????????????? : COMPLETED
Started at??????????????????????? : 06/03/2012 00:07:58
Completed at????????????????????? : 06/03/2012 00:07:59
Number of SQL Profile Findings??? : 1

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘MY_TASK_NAME01‘)
--------------------------------------------------------------------------------
-------------------------------------------------------------------------------
Schema Name: SCOTT
SQL ID???? : ga3q5tqjgsj5u
SQL Text?? : select/*+ full(t)*/ count(1) from scott.tb_test t where t.id=1

-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------

1- SQL Profile Finding (see explain plans section below)
--------------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘MY_TASK_NAME01‘)
--------------------------------------------------------------------------------
? A potentially better execution plan was found for this statement.

? Recommendation (estimated benefit: 84.11%)
? ------------------------------------------
? - Consider accepting the recommended SQL profile.
??? execute dbms_sqltune.accept_sql_profile(task_name => ‘task_name01‘,
??????????? replace => TRUE);

-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------

1- Original With Adjusted Cost
------------------------------
Plan hash value: 1372292586

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

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

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

-- 当前的运行计划
DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------
|?? 0 | SELECT STATEMENT?? |?????????? |???? 1 |???? 4 |???? 6?? (0)| 00:00:01 |

|?? 1 |? SORT AGGREGATE??? |?????????? |???? 1 |???? 4 |??????????? |????????? |

|*? 2 |?? TABLE ACCESS FULL| TB_TEST? ?|???? 1 |???? 4 |???? 6?? (0)| 00:00:01 |

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

Predicate Information (identified by operation id):
---------------------------------------------------

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------

?? 2 - filter("T"."ID"=1)

?

-- Oracle给出的运行计划

2- Using SQL Profile
--------------------
Plan hash value: 847665939

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

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
---
|?? 0 | SELECT STATEMENT? |?????????????? |???? 1 |???? 4 |???? 1?? (0)| 00:00:0
1 |
|?? 1 |? SORT AGGREGATE?? |?????????????? |???? 1 |???? 4 |??????????? |
? |
|*? 2 |?? INDEX RANGE SCAN| IDX_TB_TEST? ?|???? 1 |???? 4 |???? 1?? (0)| 00:00:0
1 |
--------------------------------------------------------------------------------
---

DBMS_SQLTUNE.REPORT_TUNING_TASK(‘TASK_NAME01‘)
--------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------

?? 2 - access("T"."ID"=1)

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

从上面的输出能够看出Oracle给出的运行计划是正确的.能够使用例如以下方法使用正确的运行计划

begin
? dbms_sqltune.accept_sql_profile(task_name => ‘task_name01‘, replace => TRUE);
end;

-- The End --

原文地址:https://www.cnblogs.com/mqxnongmin/p/10746325.html

时间: 2024-10-09 21:02:30

使用hint优化Oracle的运行计划 以及 SQL Tune Advisor的使用的相关文章

使用hint优化Oracle的执行计划

背景: 某表忽然出现查询非常缓慢的情况,cost 100+ 秒以上:严重影响生产. 原SQL: explain plan for select * from ( select ID id,RET_NO retNo, FROM_SYS fromSy, TO_SYS toSys, COMMAND_CODE commandCode, COMMAND, STATUS, EXT_CODE, ORIGN_CODE orignCode,error_message errorMessage, RE_F, RET

[Oracle] 获取运行计划的各方法总结

总的结论: 一.获取运行计划的6种方法(具体步骤已经在每一个样例的开头凝视部分说明了): 1. explain plan for获取: 2. set autotrace on . 3. statistics_level=all; 4. 通过dbms_xplan.display_cursor输入sql_id參数直接获取 5. 10046 trace跟踪 6. awrsqrpt.sql 二.适用场合分析 1.假设某SQL运行很长时间才会出结果.甚至慢到返回不了结果,这时候看运行计划就仅仅能用方法1,

oracle分区表运行计划

分区表有非常多优点,以大化小,一小化了,加上并行的使用,在loap中能往往能提高几十倍甚至几百倍的效果. 当然表设计得不好也会适得其反.效果比普通表跟糟糕. 为了更好的使用分区表,这里看一下分区表的运行计划. PARTITION RANGE ALL:扫描全部分区 PARTITION RANGE ITERATOR:扫描多个分区,小于全部个分区数量 PARTITION RANGE SINGLE:扫描单一的分区 KEY,表示运行时才知道哪个分区 看到keywordALL的时候就要注意了,扫描的是全部分

Oracle优化器和执行计划

1. 优化器(Optimizer)是sql分析和执行的优化工具,它负责制定sql的执行计划,负责保证sql执行效率最高,比如决定oracle以什么方式访问数据,全表扫描(full table scan)还是索引范围(index range scan)扫描,还是全索引快速扫描(index fast full scan, INDEX_FFS),对于表关联查询,是用什么方式关联.有2种优化器,RBO和CBO,从oracle 10g开始,RBO已经被弃用,但是仍可以通过hint的方式使用. 2. RBO

分析oracle的执行计划(explain plan)并对对sql进行优化实践

基于oracle的应用系统很多性能问题,是由应用系统sql性能低劣引起的,所以,sql的性能优化很重要,分析与优化sql的性能我们一般通过查看该sql的执行计划,本文就如何看懂执行计划,以及如何通过分析执行计划对sql进行优化做相应说明. 一.什么是执行计划(explain plan) 执行计划:一条查询语句在oracle中的执行过程或访问路径的描述. 二.如何查看执行计划 1.set autotrace on 2.explain plan for sql语句; select plan_tabl

[z]Oracle性能优化-读懂执行计划

http://blog.csdn.net/lifetragedy/article/details/51320192 Oracle的执行计划 得到执行计划的方式 Autotrace例子 使用Explain [sql] view plain copy explain plan set STATEMENT_ID='testplan' for select * from dual; [sql] view plain copy select lpad(' ',5*(level-1))||operation

Oracle性能优化-读懂执行计划

Oracle的执行计划 得到执行计划的方式 Autotrace例子 使用Explain explain plan set STATEMENT_ID='testplan' for select * from dual; select lpad(' ',5*(level-1))||operation operation, options, object_name, cost,position from plan_table start with id=0 and STATEMENT_ID='test

【故障处理141119】一次数据库不繁忙时一条sql语句2个运行计划导致业务超时的故障处理

1,故障描写叙述: 一条select有两个运行计划.在sqlplus中运行选择好的运行计划.仅仅要40毫秒.而在程序中运行选择了差的运行计划,要1分23秒左右,导致前台业务超时报错. 2.故障解决: 使用outline固定好的运行计划后攻克了该故障. 3,故障发展顺序: (1),早上一上班,说CRM的一个业务报错,crm应用开发者.接口的.tuxdo.dba集中到一起開始诊断错误. (2),业务返回超时错误 (3),数据库这边抓取AWR报告发现例如以下信息: (4),此时应用开发者也发过来了该条

Oracle固定SQL的执行计划(一)---SQL Profile

我们都希望对于所有在Oracle数据库中执行的SQL,CBO都能产生出正确的执行计划,但实际情况却并非如此,由于各种各样的原因(比如目标SQL所涉及的对象的统计信息的不准确,或者CBO内部一些成本计算公式的先天缺陷等),导致有时CBO产生效率不高.甚至是错误的执行计划.特别是CBO对目标SQL所产生的初始执行计划是正确的,后来由于某种原因(比如统计信息的变更等)而导致CBO重新对其产生了错误的执行计划,这种执行计划的改变往往会导致目标SQL执行时间呈数量级的递增,而且常常会让我们很困惑:这个SQ