--环境 scott@ORA11G> select * from v$version where rownum<2;
BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
--创建演示表 scott@ORA11G> CREATE TABLE t 2 NOLOGGING 3 AS 4 SELECT * 5 FROM dba_source, 6 ( SELECT * 7 FROM DUAL 8 CONNECT BY ROWNUM < 5);
Table created.
--执行SQL 语句 scott@ORA11G> SELECT COUNT (*) 2 FROM t a 3 WHERE a.ROWID > (SELECT MIN (b.ROWID) 4 FROM t b 5 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line);
COUNT(*) ---------- 1872756
1 row selected.
--开始SQL自动调整并报告结果 --脚本tune_last_sql.sql中包含了创建调优任务、开始执行调优、以及报告调优成果。脚本内容见文章尾部 scott@ORA11G> @tune_last_sql
RECS ----------------------------------------------------------------------------------------- GENERAL INFORMATION SECTION ------------------------------------------------------------------------------- Tuning Task Name : TASK_833 Tuning Task Owner : SCOTT Workload Type : Single SQL Statement Scope : COMPREHENSIVE Time Limit(seconds): 1800 Completion Status : COMPLETED Started at : 05/22/2013 15:06:06 Completed at : 05/22/2013 15:07:17
------------------------------------------------------------------------------- Schema Name: SCOTT SQL ID : 44tg722u0ypqh SQL Text : SELECT COUNT (*) FROM t a WHERE a.ROWID > (SELECT MIN (b.ROWID) FROM t b WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line)
------------------------------------------------------------------------------- FINDINGS SECTION (1 finding) -------------------------------------------------------------------------------
1- Statistics Finding --------------------- Table "SCOTT"."T" was not analyzed.
Recommendation -------------- - Consider collecting optimizer statistics for this table. execute dbms_stats.gather_table_stats(ownname => 'SCOTT', tabname => 'T', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt => 'FOR ALL COLUMNS SIZE AUTO');
Rationale --------- The optimizer requires up-to-date statistics for the table in order to select a good execution plan.
------------------------------------------------------------------------------- EXPLAIN PLANS SECTION -------------------------------------------------------------------------------
1- Original ----------- Plan hash value: 1985065416
----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 134 | | 42648 (1)| 00:08:32 | | 1 | SORT AGGREGATE | | 1 | 134 | | | | |* 2 | HASH JOIN | | 129K| 16M| 195M| 42648 (1)| 00:08:32 | | 3 | TABLE ACCESS FULL | T | 2590K| 165M| | 11596 (1)| 00:02:20 | | 4 | VIEW | VW_SQ_1 | 2590K| 165M| | 11674 (1)| 00:02:21 | | 5 | HASH GROUP BY | | 2590K| 165M| | 11674 (1)| 00:02:21 | | 6 | TABLE ACCESS FULL| T | 2590K| 165M| | 11596 (1)| 00:02:20 | -----------------------------------------------------------------------------------------
Predicate Information (identified by operation id): ---------------------------------------------------
2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND "A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4") filter("A".ROWID>"MIN(B.ROWID)")
--上面的report总共分为3个部分,分别是SQL调优的基本信息、SQL调优的建议findings、以及SQL对应的执行计划部分 --在基本信息部分包含了SQL调优的任务名称,状态,执行,完成时间,对应的SQL完整语句等 --在finding部分则给出本次调优所得到的成果,如本次是提示缺少统计信息 --在执行计划部分则给出了当前SQL语句的执行计划以及谓词信息
-->接下来根据建议来收集统计信息 scott@ORA11G> BEGIN 2 DBMS_STATS.gather_table_stats (ownname => 'SCOTT', 3 tabname => 'T', 4 estimate_percent => DBMS_STATS.auto_sample_size, 5 method_opt => 'FOR ALL COLUMNS SIZE AUTO'); 6 END; 7 /
PL/SQL procedure successfully completed.
-->对原SQL语句增加order提示并执行 scott@ORA11G> SELECT /*+ ordered */COUNT (*) 2 FROM t a 3 WHERE a.ROWID > (SELECT MIN (b.ROWID) 4 FROM t b 5 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line);
COUNT(*) ---------- 1872756
1 row selected.
--再次调优SQL语句 scott@ORA11G> @tune_last_sql
RECS ----------------------------------------------------------------------------------------------- GENERAL INFORMATION SECTION ------------------------------------------------------------------------------- Tuning Task Name : TASK_849 Tuning Task Owner : SCOTT Workload Type : Single SQL Statement Scope : COMPREHENSIVE Time Limit(seconds): 1800 Completion Status : COMPLETED Started at : 05/22/2013 21:26:07 Completed at : 05/22/2013 21:26:42
------------------------------------------------------------------------------- Schema Name: SCOTT SQL ID : fsp3852n56gf8 SQL Text : SELECT /*+ ordered */COUNT (*) FROM t a WHERE a.ROWID > (SELECT MIN (b.ROWID) from t b WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE AND a.line = b.line)
------------------------------------------------------------------------------- FINDINGS SECTION (1 finding) -------------------------------------------------------------------------------
1- SQL Profile Finding (see explain plans section below) -------------------------------------------------------- A potentially better execution plan was found for this statement.
Recommendation (estimated benefit: 67.95%) ------------------------------------------ - Consider accepting the recommended SQL profile. execute dbms_sqltune.accept_sql_profile(task_name => 'TASK_849', task_owner => 'SCOTT', replace => TRUE);
------------------------------------------------------------------------------- EXPLAIN PLANS SECTION -------------------------------------------------------------------------------
1- Original With Adjusted Cost ------------------------------ Plan hash value: 2929971977
-------------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | -------------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | | | 218K (1)| 00:43:47 | | 1 | SORT AGGREGATE | | 1 | | | | | | 2 | VIEW | VM_NWVW_2 | 551K| | | 218K (1)| 00:43:47 | |* 3 | FILTER | | | | | | | | 4 | HASH GROUP BY | | 551K| 51M| 1197M| 218K (1)| 00:43:47 | |* 5 | HASH JOIN | | 11M| 1031M| 145M| 37646 (1)| 00:07:32 | | 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 | | 7 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 | --------------------------------------------------------------------------------------------
Predicate Information (identified by operation id): ---------------------------------------------------
3 - filter("A".ROWID>MIN("B".ROWID)) 5 - access("A"."OWNER"="B"."OWNER" AND "A"."NAME"="B"."NAME" AND "A"."TYPE"="B"."TYPE" AND "A"."LINE"="B"."LINE")
2- Using SQL Profile -------------------- Plan hash value: 1985065416
----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 116 | | 70117 (1)| 00:14:02 | | 1 | SORT AGGREGATE | | 1 | 116 | | | | |* 2 | HASH JOIN | | 2025K| 224M| 145M| 70117 (1)| 00:14:02 | | 3 | TABLE ACCESS FULL | T | 2497K| 116M| | 11596 (1)| 00:02:20 | | 4 | VIEW | VW_SQ_1 | 2497K| 159M| | 41851 (1)| 00:08:23 | | 5 | HASH GROUP BY | | 2497K| 116M| 153M| 41851 (1)| 00:08:23 | | 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 | -----------------------------------------------------------------------------------------
Predicate Information (identified by operation id): ---------------------------------------------------
2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND "A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4") filter("A".ROWID>"MIN(B.ROWID)")
-------------------------------------------------------------------------------
--针对上述的SQL语句,SQL调优器找到了一个更为高效的执行计划,并提示我们接受该执行计划,如下 --A potentially better execution plan was found for this statement. --Recommendation (estimated benefit: 67.95%) --Consider accepting the recommended SQL profile
--Author : Robinson --Blog : http://blog.csdn.net/robinson_0612
--接受SQL profile scott@ORA11G> exec DBMS_SQLTUNE.accept_sql_profile (task_name => 'TASK_849', task_owner => 'SCOTT', REPLACE => TRUE);
PL/SQL procedure successfully completed.
--当接受SQL profile后,我们再次来执行原来带order提示的SQL语句 scott@ORA11G> set autot trace exp; scott@ORA11G> SELECT /*+ ordered */COUNT (*) 2 FROM t a 3 WHERE a.ROWID > (SELECT MIN (b.ROWID) from t b 4 WHERE a.owner = b.owner AND a.name = b.name AND a.TYPE = b.TYPE 5 AND a.line = b.line);
Execution Plan ---------------------------------------------------------- Plan hash value: 1985065416
----------------------------------------------------------------------------------------- | Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time | ----------------------------------------------------------------------------------------- | 0 | SELECT STATEMENT | | 1 | 116 | | 70117 (1)| 00:14:02 | | 1 | SORT AGGREGATE | | 1 | 116 | | | | |* 2 | HASH JOIN | | 2025K| 224M| 145M| 70117 (1)| 00:14:02 | | 3 | TABLE ACCESS FULL | T | 2497K| 116M| | 11596 (1)| 00:02:20 | | 4 | VIEW | VW_SQ_1 | 2497K| 159M| | 41851 (1)| 00:08:23 | | 5 | HASH GROUP BY | | 2497K| 116M| 153M| 41851 (1)| 00:08:23 | | 6 | TABLE ACCESS FULL| T | 2497K| 116M| | 11596 (1)| 00:02:20 | -----------------------------------------------------------------------------------------
Predicate Information (identified by operation id): ---------------------------------------------------
2 - access("A"."OWNER"="ITEM_1" AND "A"."NAME"="ITEM_2" AND "A"."TYPE"="ITEM_3" AND "A"."LINE"="ITEM_4") filter("A".ROWID>"MIN(B.ROWID)")
Note ----- - SQL profile "SYS_SQLPROF_013ecc70b5f70000" used for this statement
scott@ORA11G> set autot off;
--上面的autotrace中,最后一部分表明当前的SQL语句使用了存储的SQL profile的执行计划 |