SQL优化篇--SQL TUNNING ADVICER使用

–STA调优(SQL文本)

DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
my_sqltext := ‘select * from CUST_OB where object_name=’‘I_CDEF2’’’;
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
user_name => ‘CRM’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘tuning_sql_test1’,
description => ‘Task to tune a query on a specified table’);
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘tuning_sql_test1’);
END;
/

–STA调优(sqlid)

DECLARE
my_task_name VARCHAR2(30);
BEGIN
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_id => ‘18k3qg9cr050h’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘tuning_sql_test2’,
description => ‘Task to tune a query on a specified table’);
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘tuning_sql_test2’);
END;
/

–查看生成的STA报告

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( ‘tuning_sql_test1’) from DUAL;

–删除STA任务

begin
DBMS_SQLTUNE.DROP_TUNING_TASK(‘tuning_sql_test1’);
end;

一、创建测试数据

登陆fst用户

create table obj as select * from dba_objects;
exec dbms_stats.gather_table_stats(ownname=>‘FST’,tabname=>‘OB’,estimate_percent=>100,no_invalidate=>False,Cascade=>True);

二、使用STA调优SQL语句

1、根据sql语句调优

–1.1 创建优化任务并执行

DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
my_sqltext := ‘select * from obj where object_id=101’;
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
user_name => ‘FST’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘tuning_sql_test1’,
description => ‘Task to tune a query on a specified table’);
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘tuning_sql_test1’);
END;
/

–1.2 查看优化任务是否完成,并查看优化结果

select task_name, status from USER_ADVISOR_LOG where task_name=‘tuning_sql_test1’;

在这里插入图片描述

SELECT sofar, totalwork FROM V$ADVISOR_PROGRESS;

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( ‘tuning_sql_test1’) from DUAL;

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : tuning_sql_test1
Tuning Task Owner  : FST
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status  : COMPLETED
Started at         : 10/24/2018 10:47:24
Completed at       : 10/24/2018 10:47:25
 
-------------------------------------------------------------------------------
Schema Name: FST
SQL ID     : 1rk75xx3gns81
SQL Text   : select * from obj where object_id=101
 
-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------
 
1- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.
 
  Recommendation (estimated benefit: 99.42%)
  ------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index FST.IDX$$_0BF90001 on FST.OBJ("OBJECT_ID");
 
  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.
 
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
 
1- Original
-----------
Plan hash value: 730912574
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     1 |    98 |   347   (1)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| OBJ  |     1 |    98 |   347   (1)| 00:00:05 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("OBJECT_ID"=101)
 
2- Using New Indices
--------------------
Plan hash value: 3281391003
 
----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |     1 |    98 |     2   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| OBJ            |     1 |    98 |     2   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX$$_0BF90001 |     1 |       |     1   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("OBJECT_ID"=101)
 
-------------------------------------------------------------------------------

–1.3删除优化任务

begin DBMS_SQLTUNE.DROP_TUNING_TASK(‘tuning_sql_test1’); end;

2、根据sql_id调优

多次执行下面的SQL

select * from obj where object_name = ‘I_CDEF2’;

–根据sql文本查询sql_id:

select sql_text,sql_id from v$sqlarea where sql_text like ‘%select *
from obj where object_name%’; 18k3qg9cr050h

–2.1 创建优化任务并执行

DECLARE my_task_name VARCHAR2(30); BEGIN my_task_name :=
DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_id => ‘18k3qg9cr050h’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘tuning_sql_test2’,
description => ‘Task to tune a query on a specified table’); DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘tuning_sql_test2’);
END; /

–2.2 查看优化任务是否完成,并查看优化结果

select task_name, status from USER_ADVISOR_LOG where
task_name=‘tuning_sql_test2’;

在这里插入图片描述

SELECT sofar, totalwork FROM V$ADVISOR_PROGRESS;

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK( ‘tuning_sql_test2’) from DUAL;

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : tuning_sql_test2
Tuning Task Owner  : FST
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status  : COMPLETED
Started at         : 10/24/2018 11:03:06
Completed at       : 10/24/2018 11:03:07
 
-------------------------------------------------------------------------------
Schema Name: FST
SQL ID     : 18k3qg9cr050h
SQL Text   : select * from obj where object_name = 'I_CDEF2'
 
-------------------------------------------------------------------------------
FINDINGS SECTION (1 finding)
-------------------------------------------------------------------------------
 
1- Index Finding (see explain plans section below)
--------------------------------------------------
  The execution plan of this statement can be improved by creating one or more
  indices.
 
  Recommendation (estimated benefit: 98.84%)
  ------------------------------------------
  - Consider running the Access Advisor to improve the physical schema design
    or creating the recommended index.
    create index FST.IDX$$_0BFB0001 on FST.OBJ("OBJECT_NAME");
 
  Rationale
  ---------
    Creating the recommended indices significantly improves the execution plan
    of this statement. However, it might be preferable to run "Access Advisor"
    using a representative SQL workload as opposed to a single statement. This
    will allow to get comprehensive index recommendations which takes into
    account index maintenance overhead and additional space consumption.
 
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
 
1- Original
-----------
Plan hash value: 730912574
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |   196 |   347   (1)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| OBJ  |     2 |   196 |   347   (1)| 00:00:05 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("OBJECT_NAME"='I_CDEF2')
 
2- Using New Indices
--------------------
Plan hash value: 3570812727
 
----------------------------------------------------------------------------------------------
| Id  | Operation                   | Name           | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |                |     2 |   196 |     4   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| OBJ            |     2 |   196 |     4   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX$$_0BFB0001 |     2 |       |     3   (0)| 00:00:01 |
----------------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("OBJECT_NAME"='I_CDEF2')
 
-------------------------------------------------------------------------------

–2.3 删除优化任务

begin DBMS_SQLTUNE.DROP_TUNING_TASK(‘tuning_sql_test2’); end; /

3、其他优化建议
–登陆fst用户

create table ob as select * from dba_objects; create index idx2 on
ob(object_id,object_name);

–对应sql语句select * from ob where ob.object_id = 10;会走索引idx2

SQL> set autotrace traceonly SQL> select * from ob where ob.object_id
= 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 2091480331
 
------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes | Cost (%CPU)| Time    |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |    |  1 |   207 |  3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| OB   |  1 |   207 |  3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN     | IDX2 |  1 |    |  2   (0)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("OB"."OBJECT_ID"=10)
 
Note
-----
   - dynamic sampling used for this statement (level=2)
 
 
Statistics
----------------------------------------------------------
  7  recursive calls
  0  db block gets
 89  consistent gets
  0  physical reads
  0  redo size
       1612  bytes sent via SQL*Net to client
519  bytes received via SQL*Net from client
  2  SQL*Net roundtrips to/from client
  0  sorts (memory)
  0  sorts (disk)
  1  rows processed

–使用hint使sql语句走全部扫描(错误的执行计划)

SQL> select /*+ full(ob) */ * from ob where ob.object_id = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 1611727973
 
--------------------------------------------------------------------------
| Id  | Operation   | Name | Rows  | Bytes | Cost (%CPU)| Time  |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |  |     1 |   207 |   347   (1)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| OB   |     1 |   207 |   347   (1)| 00:00:05 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("OB"."OBJECT_ID"=10)
 
Note
-----
   - dynamic sampling used for this statement (level=2)
 
 
Statistics
----------------------------------------------------------
 10  recursive calls
  0  db block gets
       1334  consistent gets
881  physical reads
  0  redo size
       1609  bytes sent via SQL*Net to client
519  bytes received via SQL*Net from client
  2  SQL*Net roundtrips to/from client
  0  sorts (memory)
  0  sorts (disk)
  1  rows processed

–下面使用STA调优select /*+ full(ob) */ * from ob where ob.object_id = 10语句
–创建优化任务并执行

declare l_task_name varchar2(30); l_sql clob; begin l_sql
:= ‘select /*+ full(ob) */ * from ob where ob.object_id = 10’;
l_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text => l_sql,
user_name => ‘FST’,
scope => ‘COMPREHENSIVE’,
time_limit => 60,
task_name => ‘test01’,
description => null); end; /

–查看任务

select task_name,EXECUTION_START,EXECUTION_END,STATUS from
DBA_ADVISOR_LOG where task_name like ‘test%’;

在这里插入图片描述

–执行优化任务

BEGIN DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => ‘test01’ );
END; /

–查看调优建议结果

SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK(‘test01’) FROM DUAL;

GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name   : test01
Tuning Task Owner  : FST
Workload Type      : Single SQL Statement
Scope              : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status  : COMPLETED
Started at         : 10/24/2018 09:39:40
Completed at       : 10/24/2018 09:39:43
 
-------------------------------------------------------------------------------
Schema Name: FST
SQL ID     : adh32wcz7bz1y
SQL Text   : select /*+ full(ob) */ * from ob where ob.object_id = 10
 
-------------------------------------------------------------------------------
FINDINGS SECTION (2 findings)
-------------------------------------------------------------------------------
 
1- Statistics Finding --第一个调优建议:收集统计信息
---------------------
  Table "FST"."OB" was not analyzed.
 
  Recommendation
  --------------
  - Consider collecting optimizer statistics for this table.
    execute dbms_stats.gather_table_stats(ownname => 'FST', tabname => 'OB',
            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.
 
2- SQL Profile Finding (see explain plans section below) --第二个调优建议:使用profile绑定执行计划
--------------------------------------------------------
  A potentially better execution plan was found for this statement.
 
  Recommendation (estimated benefit: 99.75%)
  ------------------------------------------
  - Consider accepting the recommended SQL profile.
    execute dbms_sqltune.accept_sql_profile(task_name => 'test01', task_owner
            => 'FST', replace => TRUE);
 
  Validation results
  ------------------
  The SQL profile was tested by executing both its plan and the original plan
  and measuring their respective execution statistics. A plan may have been
  only partially executed if the other could be run to completion in less time.
 
                           Original Plan  With SQL Profile  % Improved
                           -------------  ----------------  ----------
  Completion Status:            COMPLETE          COMPLETE
  Elapsed Time (s):             .003867           .000014      99.63 %
  CPU Time (s):                 .002799                 0        100 %
  User I/O Time (s):                  0                 0
  Buffer Gets:                     1247                 3      99.75 %
  Physical Read Requests:             0                 0
  Physical Write Requests:            0                 0
  Physical Read Bytes:                0                 0
  Physical Write Bytes:               0                 0
  Rows Processed:                     1                 1
  Fetches:                            1                 1
  Executions:                         1                 1
 
  Notes
  -----
  1. Statistics for the original plan were averaged over 10 executions.
  2. Statistics for the SQL profile plan were averaged over 10 executions.
 
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
 
1- Original With Adjusted Cost
------------------------------
Plan hash value: 1611727973
 
--------------------------------------------------------------------------
| Id  | Operation         | Name | Rows  | Bytes | Cost (%CPU)| Time     |
--------------------------------------------------------------------------
|   0 | SELECT STATEMENT  |      |     2 |   206 |   347   (1)| 00:00:05 |
|*  1 |  TABLE ACCESS FULL| OB   |     2 |   206 |   347   (1)| 00:00:05 |
--------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   1 - filter("OB"."OBJECT_ID"=10)
 
2- Using SQL Profile
--------------------
Plan hash value: 2091480331
 
------------------------------------------------------------------------------------
| Id  | Operation                   | Name | Rows  | Bytes | Cost (%CPU)| Time     |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT            |      |     2 |   206 |     3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| OB   |     2 |   206 |     3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN          | IDX2 |     2 |       |     2   (0)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("OB"."OBJECT_ID"=10)
 
-------------------------------------------------------------------------------

–这里我们使用第二个调优建议(创建sql profile)

SQL> execute dbms_sqltune.accept_sql_profile(task_name => ‘test01’,
task_owner => ‘FST’, replace => TRUE); PL/SQL procedure successfully
completed

–再次查看 select /*+ full(ob) */ * from ob where ob.object_id = 10语句执行计划

SQL> select /*+ full(ob) */ * from ob where ob.object_id = 10;

Execution Plan
----------------------------------------------------------
Plan hash value: 2091480331
 
------------------------------------------------------------------------------------
| Id  | Operation     | Name | Rows  | Bytes | Cost (%CPU)| Time    |
------------------------------------------------------------------------------------
|   0 | SELECT STATEMENT     |    |  2 |   206 |  3   (0)| 00:00:01 |
|   1 |  TABLE ACCESS BY INDEX ROWID| OB   |  2 |   206 |  3   (0)| 00:00:01 |
|*  2 |   INDEX RANGE SCAN     | IDX2 |  2 |    |  2   (0)| 00:00:01 |
------------------------------------------------------------------------------------
 
Predicate Information (identified by operation id):
---------------------------------------------------
 
   2 - access("OB"."OBJECT_ID"=10)
 
Note
-----
   - SQL profile "SYS_SQLPROF_0166a41fe5e00001" used for this statement     --使用了sql profile
 
Statistics
----------------------------------------------------------
 10  recursive calls
  0  db block gets
 10  consistent gets
  1  physical reads
  0  redo size
       1612  bytes sent via SQL*Net to client
519  bytes received via SQL*Net from client
  2  SQL*Net roundtrips to/from client
  0  sorts (memory)
  0  sorts (disk)
  1  rows processed

你可能感兴趣的:(Oracle)