1、前言:一直以来SQL调优都是DBA比较费力的技术活,而且很多DBA如果没有从事过开发的工作,那么调优更是一项头疼的工作,即使是SQL调优很厉害的高手,在SQL调优的过程中也要不停的分析执行计划、加HINT、分析统计信息等等。从ORACLE 10G开始,数据库采取了很多智能化的管理工作,其中SQL优化器(SQL Tuning Advisor:STA),大大的提高了DBA进行SQL优化的效率;

2、原理介绍:

When SQL statements are executed by the Oracle database, the query optimizer is used to generate the execution plans of the SQL statements. The query optimizer operates in two modes: a normal mode and a tuning mode.

In normal mode, the optimizer compiles the SQL and generates an execution plan. The normal mode of the optimizer generates a reasonable execution plan for the vast majority of SQL statements. Under normal mode, the optimizer operates with very strict time constraints, usually a fraction of a second, during which it must find a good execution plan.

In tuning mode, the optimizer performs additional analysis to check whether the execution plan produced under normal mode can be improved further. The output of the query optimizer is not an execution plan, but a series of actions, along with their rationale and expected benefit for producing a significantly superior plan. When running in the tuning mode, the optimizer is referred to as the Automatic Tuning Optimizer.

Under tuning mode, the optimizer can take several minutes to tune a single statement. It is both time and resource intensive to invoke the Automatic Tuning Optimizer every time a query has to be hard-parsed. The Automatic Tuning Optimizer is meant to be used for complex and high-load SQL statements that have non-trivial impact on the entire system. The Automatic Database Diagnostic Monitor (ADDM) proactively identifies high-load SQL statements which are good candidates for SQL tuning. See Chapter 6, "Automatic Performance Diagnostics". The automatic SQL tuning feature of Oracle Database also automatically identifies problematic SQL statements and implements tuning recommendations during system maintenance windows as an automated maintenance task.

查询优化器有两种模式:普通模式与调化模式。

优化器在普通模式下,当SQL被执行时,查询优化器将生成SQL的执行计划,如果SQL的可选路径很多,优化器必须是限制时间内,选择一个合适的执行计划,查询优化器默认执行普通模式;

当优化器在调优模式下,优化器需要执行额外的分析去判断优化器在普通模式下产生的执行计划是否有可能被改进,此时优化器输出的不是一个执行计划,而是一系列的动作,根据调优的原理、产生一个更优化的执行计划,优化器需发花费一定的时间去调优单个的sql,自动调优的优化器每次查询都是硬解析。

SQL Tuning Advisor获取AWR报告中High-Load SQL,查询优化器在调优模式下生成一个最好的执行计划,从而实现SQL调优的目的;

3、功能介绍:

The Automatic Tuning Optimizer performs four types of tuning analysis:

  • Statistics Analysis
  • SQL Profiling
  • Access Path Analysis
  • SQL Structure Analysis

4、SQL Tuning Advisor的管理:

任务的查看:select * from DBA_AUTOTASK_WINDOW_CLIENTS;

任务的启动:

BEGINDBMS_AUTO_TASK_ADMIN.ENABLE(client_name => 'sql tuning advisor',operation => NULL,window_name => NULL);END;/

任务的停止:BEGINDBMS_AUTO_TASK_ADMIN.DISABLE(client_name => 'sql tuning advisor',operation => NULL,window_name => NULL);END;/

SQL Tuning Advisor结果的查看:

select dbms_sqltune.report_tuning_task('SYS_AUTO_SQL_TUNING_TASK') from dual;

5、手工运行SQL Tuning Advisor进行调优

说明:创建两张大表和小表,并且都没创建索引,然后进行关联。通过执行SQL Tuning Advisor得到优化建议

步骤一:创建表

脚本:create table hr.big as select rownum as "id",a.* from sys.all_objects a;

脚本:create table hr.small as select rownum as "id", a.* FROM sys.all_tables a;

然后多运行几次下面的脚本,增加表里的数据:

insert into hr.big select * from hr.big;

insert into hr.small select * from hr.small;

SQL> select count(*) from hr.small;

COUNT(*)

----------

2835

SQL> select count(*) from hr.big;

COUNT(*)

----------

727438

步骤二:直接进行关联测试

SQL> set timing on

SQL> set autot on

SQL> select count(*) from hr.big a, hr.small b where a.object_name=b.table_name;

COUNT(*)

----------

31500

Elapsed: 00:00:00.50

Execution Plan

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

Plan hash value: 1355302734

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

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

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

| 0 | SELECT STATEMENT |     |     1 |     34 | 3064 (1)| 00:00:37 |

| 1 | SORT AGGREGATE |     |     1 |     34 |         |     |

|* 2 | HASH JOIN     |     |    453K|     14M| 3064 (1)| 00:00:37 |

| 3 | TABLE ACCESS FULL| SMALL | 2915 | 49555 |     31 (0)| 00:00:01 |

| 4 | TABLE ACCESS FULL| BIG |    610K|     9M| 3029 (1)| 00:00:37 |

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

Predicate Information (identified by operation id):

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

2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")

Note

-----

- dynamic sampling used for this statement (level=2)

Statistics

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

10 recursive calls

2 db block gets

11362 consistent gets

6332 physical reads

0 redo size

527 bytes sent via SQL*Net to client

523 bytes received via SQL*Net from client

2 SQL*Net roundtrips to/from client

2 sorts (memory)

0 sorts (disk)

1 rows processed

步骤三:创建优化任务

通过调用函数CREATE_TUNING_TASK来创建优化任务,调用存储过程EXECUTE_TUNING_TASK执行该任务:

SQL> set autot off

SQL> set timing off

SQL> DECLARE

my_task_name VARCHAR2(30);

my_sqltext CLOB;

BEGIN

my_sqltext := 'select count(*) from hr.big a, hr.small b where a.object_name=b.table_name';

my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(

sql_text => my_sqltext,

user_name => 'HR',

scope => 'COMPREHENSIVE',

time_limit => 60,

task_name => 'tuning_sql_test',

description => 'Task to tune a query on a specified table');

DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'tuning_sql_test');

END;

/

函数CREATE_TUNING_TASK说明:

  • sql_text是需要优化的语句
  • user_name是该语句通过哪个用户执行,注意是大写,不然会报错,用户无效
  • scope是优化范围(limited或comprehensive),
  • time_limit优化过程的时间限制,
  • task_name优化任务名称,
  • description优化任务描述。

步骤四: 执行优化任务

通过调用dbms_sqltune.execute_tuning_task过程来执行前面创建好的优化任务。

SQL> exec dbms_sqltune.execute_tuning_task('tuning_sql_test');

步骤五:检查优化任务的状态

通过查看user_advisor_tasks/dba_advisor_tasks视图可以查看优化任务的当前状态。

SQL> SELECT task_name,status FROM USER_ADVISOR_TASKS WHERE task_name='tuning_sql_test';

TASK_NAME STATUS

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

tuning_sql_test COMPLETED

步骤六:查看优化结果

通过dbms_sqltune.report_tning_task函数可以获得优化任务的结果。

SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( 'tuning_sql_test') from DUAL;

GENERAL INFORMATION SECTION

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

Tuning Task Name : tuning_sql_test

Tuning Task Owner : SYS

Workload Type : Single SQL Statement

Execution Count : 2

Current Execution : EXEC_12

Execution Type : TUNE SQL

Scope : COMPREHENSIVE

Time Limit(seconds): 60

Completion Status : COMPLETED

Started at : 12/30/2013 15:56:04

Completed at : 12/30/2013 15:56:06

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

Schema Name: HR

SQL ID : 6fnz11x82cuv4

SQL Text : select count(*) from hr.big a, hr.small b where

a.object_name=b.table_name

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

FINDINGS SECTION (3 findings)

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

1- Statistics Finding

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

????? "HR"."SMALL"?

Recommendation

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

- ????????????????

execute dbms_stats.gather_table_stats(ownname => 'HR', tabname =>

'SMALL', estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE,

method_opt => 'FOR ALL COLUMNS SIZE AUTO');

Rationale

---------

??????????, ????????????????

2- Statistics Finding

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

????? "HR"."BIG"?

Recommendation

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

- ????????????????

execute dbms_stats.gather_table_stats(ownname => 'HR', tabname => 'BIG',

estimate_percent => DBMS_STATS.AUTO_SAMPLE_SIZE, method_opt =>

'FOR ALL COLUMNS SIZE AUTO');

Rationale

---------

??????????, ????????????????

3- Index Finding (see explain plans section below)

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

????????????????????????

Recommendation (estimated benefit: 67.55%)

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

- ?????????????????????????????

create index HR.IDX$$_00150001 on HR.SMALL("TABLE_NAME");

- ?????????????????????????????

create index HR.IDX$$_00150002 on HR.BIG("OBJECT_NAME");

Rationale

---------

?????????????????????????, ????? SQL ????? "????"

?????????????????????????????, ????????????????????

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

EXPLAIN PLANS SECTION

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

1- Original

-----------

Plan hash value: 1355302734

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

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

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

| 0 | SELECT STATEMENT | | 1 | 34 | 3064 (1)| 00:00:37 |

| 1 | SORT AGGREGATE | | 1 | 34 | | |

|* 2 | HASH JOIN | | 453K| 14M| 3064 (1)| 00:00:37 |

| 3 | TABLE ACCESS FULL| SMALL | 2915 | 49555 | 31 (0)| 00:00:01 |

| 4 | TABLE ACCESS FULL| BIG | 610K| 9M| 3029 (1)| 00:00:37 |

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

Predicate Information (identified by operation id):

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

2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")

2- Using New Indices

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

Plan hash value: 3519661237

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

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

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

| 0 | SELECT STATEMENT | | 1 | 34 | 994 (2)| 00:00:12 |

| 1 | SORT AGGREGATE | | 1 | 34 | | |

|* 2 | HASH JOIN | | 453K| 14M| 994 (2)| 00:00:12 |

| 3 | INDEX FAST FULL SCAN| IDX$$_00150001 | 2915 | 49555 | 12 (0)| 00:00:01 |

| 4 | INDEX FAST FULL SCAN| IDX$$_00150002 | 610K| 9M| 978 (1)| 00:00:12 |

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

Predicate Information (identified by operation id):

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

2 - access("A"."OBJECT_NAME"="B"."TABLE_NAME")

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

解读报告:

红色部分:关于这次优化任务的基本信息:如任务名称、执行时间、范围、涉及到的语句等等。

绿色部分:关于这次优化任务的所找到的问题以及给出的优化建议。

  • 运行SMALL表的统计信息的收集;
  • 运行BIG表统计信息的收集;
  • 进行索引的添加;

蓝色部分:优化前和优化后的执行计划的对比,可以看出COST值大大下降。

五、删除优化任务

通过调用dbms_sqltuen.drop_tuning_task可以删除已经存在的优化任务

SQL>exec dbms_sqltune.drop_tuning_task('tuning_sql_test');

PL/SQL procedure successfully completed.

总结:SQL Tuning Advisor为DBA的调优工作减轻了不少负担,一般情况下我也是通过这种方法进行调优的,这里有点小小的建议:

  1. 工具毕竟是固定的,一般只会针对单个语句给出建议,不会在整个数据库的整体性能上面去思考该调优方法是否可行,这点必须由DBA把握;
  2. DBA还是有必要了解为什么要这么调优,才能更好的根据实际情况给出具体的调优办法,不然调优这种高大上的工作将变得廉价。

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

本文作者:JOHN

ORACLE技术博客:ORACLE 猎人笔记               数据库技术群:367875324 (请备注ORACLE管理 )

+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

深入了解SQL Tuning Advisor(转载)的更多相关文章

  1. SQL Tuning 基础概述08 - SQL Tuning Advisor

    SQL调优顾问 SQL Tuning Advisor的使用案例: 1.构建测试表T 2.定义调整任务 3.修改调整任务参数 4.执行调整任务 5.监控调整任务 6.查看调整任务建议 7.删除调整任务 ...

  2. 【转】使用SQL Tuning Advisor STA优化SQL

    SQL优化器(SQL Tuning Advisor STA)是Oracle10g中推出的帮助DBA优化工具,它的特点是简单.智能,DBA值需要调用函数就可以给出一个性能很差的语句的优化结果.下面介绍一 ...

  3. 如何用 SQL Tuning Advisor (STA) 优化SQL语句

    在Oracle10g之前,优化SQL是个比较费力的技术活,不停的分析执行计划,加hint,分析统计信息等等.在10g中,Oracle推出了自己的SQL优化辅助工具: SQL优化器(SQL Tuning ...

  4. sql tuning advisor使用

    DB tuning advisor是创建优化任务,对某些sql数据库进行分析,并尽量给出优化建议的一个强大的数据库工具. 自己平时几乎没用过这玩意,所以来测一测用法,其实对于一些sql一筹莫展的时候跑 ...

  5. Oracle 10G强大的SQL优化工具:SQL Tuning Advisor

    p { margin-bottom: 0.25cm; direction: ltr; color: rgb(0, 0, 0); line-height: 120%; orphans: 2; widow ...

  6. 使用ORACLE SQL Tuning advisor快速优化低效的SQL语句

    ORACLE10G以后版本的SQL Tuning advisor可以从以下四个方面给出优化方案 (1)为统计信息丢失或失效的对象收集统计信息   (2)考虑优化器的任何数据偏差.复杂谓词或失效的统计信 ...

  7. How to use STA(sql tuning advisor)

    一.手工生成Sql tuning advisor  1.SQL text format: DECLARE   my_task_name VARCHAR2(30);   my_sqltext   CLO ...

  8. Oracle调整顾问(SQL Tuning Advisor 与 SQL Access Advisor

    在Oracle数据库出现性能问题时,使用Oracle本身的工具包,给出合理的调优建议是比较省力的做法. tuning advisor 是对输入的sql set的执行计划进行优化accsee advis ...

  9. SQL Tuning Advisor

    SQL Tuning Advisorsql调优顾问可提供的建议有:-收集对象的统计信息-创建索引-重写sql语句-创建sql profile-创建sql plan baseline SQL Tunin ...

随机推荐

  1. ASP.NET MVC4 异常拦截

    ASP.NET MVC4 程序发生异常时,通过拦截Action的异常,重写ActionFilterAttribute 的方法OnActionExecuted实现. 具体实现代码如下: /// < ...

  2. addLoadEvent

    function addLoadEvent(func){ var oldOnload = window.onload; if(typeof(window.onload) != 'function'){ ...

  3. Stochastic Multiple Choice Learning for Training Diverse Deep Ensembles

    作者提出的方法是Algotithm 2.简单来说就是,训练的时候,在几个模型中,选取预测最准确的(也就是loss最低的)模型进行权重更新.

  4. TensorFlow基础笔记(2) minist分类学习

    (1) 最简单的神经网络分类器 # encoding: UTF-8 import tensorflow as tf from tensorflow.examples.tutorials.mnist i ...

  5. 【BZOJ】1651: [Usaco2006 Feb]Stall Reservations 专用牛棚(线段树/前缀和 + 差分)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1651 很奇妙.. 我们发现,每一时刻的重叠数选最大的就是答案.... orz 那么我们可以线段树维护 ...

  6. 【BZOJ】1624: [Usaco2008 Open] Clear And Present Danger 寻宝之路(floyd)

    http://www.lydsy.com/JudgeOnline/problem.php?id=1624 一开始我打算一个个最短路................................. 然 ...

  7. Maven中将所有依赖的jar包全部导出到文件夹

    因为我要对Java类的功能在生产环境(服务器端)进行测试,所以需要将jar包导出,然后在服务器端用-Djava.ext.dirs=./lib的方式走一遍, 下面是解决方案: 在pom.xml中加入如下 ...

  8. 将execel表格的数据导入到mysql数据库

    在开发中经常会将现成的execel表格导入到数据库里,否则一个个字段插入填写,太浪费时间,效率很低.本文主要是讲如果将execel表格导入到mysql数据库,希望对各位有所帮助.使用软件:sql工具: ...

  9. jQuery实现tag便签去重效果的方法

    本文实例讲述了jQuery实现tag便签去重效果的方法.分享给大家供大家参考.具体实现方法如下: html代码如下: <head><script type="text/ja ...

  10. 《jquery权威指南2》学习笔记------ jquery获取复选框的值

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/ ...