d、建议SQL调优集(批量tuning)
【实例】
查看版本
SQL> select * from v$version where rownum<2;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - Production
创建演示表
SQL> CREATE TABLE t NOLOGGING AS SELECT * FROM dba_source, (SELECT * FROM DUAL CONNECT BY ROWNUM < 5);
SQL> execute dbms_stats.gather_table_stats(ownname => 'SYS', tabname => 'T',estimate_percent => 50);
查看SQL执行计划
SQL> explain plan for 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);
SQL> select * from table(dbms_xplan.display());
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 134 | | 44522 (1)| 00:08:55 |
| 1 | SORT AGGREGATE | | 1 | 134 | | | |
|* 2 | HASH JOIN | | 138K| 17M| 208M| 44522 (1)| 00:08:55 |
| 3 | VIEW | VW_SQ_1 | 2764K| 176M| | 11960 (1)| 00:02:24 |
| 4 | HASH GROUP BY | | 2764K| 176M| | 11960 (1)| 00:02:24 |
| 5 | TABLE ACCESS FULL| T | 2764K| 176M| | 11887 (1)| 00:02:23 |
| 6 | TABLE ACCESS FULL | T | 2764K| 176M| | 11887 (1)| 00:02:23 |
-----------------------------------------------------------------------------------------
下面就用DBMS_SQLTUNE优化该SQL
--1.如无权限,需要赋予用户ADVISOR权限
grant ADVISOR to test;
--2.创建sql tuning任务
DECLARE
my_task_name VARCHAR2(30);
my_sqltext CLOB;
BEGIN
--my_sqltext := 'select * from emp where ename= :name and DEPTNO= :deptno';
my_sqltext := '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)';
my_task_name := DBMS_SQLTUNE.CREATE_TUNING_TASK(
sql_text => my_sqltext,
--bind_list => sql_binds(anydata.convertvarchar2(10),anydata.convertnumber(2)),
--user_name => 'TEST',
scope => 'COMPREHENSIVE',
time_limit => 60,
task_name => 'test_sql_tuning',
description => 'Task to tune a query on table T');
END;
/
参数说明:
bind_list:多个绑定变量以','逗号分隔。参数值一定要根据绑定变量对应的列的类型书写.
如:emp.ename类型是VARCHAR2(10),那么就要写成 bind_list =>sql_binds(anydata.convertvarchar2(10)),
time_limit:执行的最长时间,默认是60。
scope:
LIMITED,用大概1秒时间去优化SQL语句,但是并不进行SQL Profiling分析。
COMPREHENSIVE,进行全面分析,包含SQL Profiling分析;比LIMITED用时更长。
--3.查看任务
SQL> SELECT OWNER,TASK_ID,TASK_NAME,STATUS FROM DBA_ADVISOR_LOG WHERE TASK_NAME='test_sql_tuning';
OWNER TASK_ID TASK_NAME STATUS
---------- ---------- -------------------- -----------
SYS 8674 test_sql_tuning INITIAL
--4.执行sql tuning任务
BEGIN
DBMS_SQLTUNE.EXECUTE_TUNING_TASK( task_name => 'test_sql_tuning' );
END;
/
--5.查看SQL TUNING状态
SQL> SELECT status FROM USER_ADVISOR_TASKS WHERE task_name = 'test_sql_tuning';
STATUS
-----------
COMPLETED
--6.展示sql tunning结果
SET LONG 10000
SET LONGCHUNKSIZE 1000
SET LINESIZE 100
SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('test_sql_tuning') FROM DUAL;
结果中会给出一些建议,比如建议我们锁定SQL profile或者创建索引等:
SQL> SELECT DBMS_SQLTUNE.REPORT_TUNING_TASK('test_sql_tuning') FROM DUAL;
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : test_sql_tuning
Tuning Task Owner : SYS
Workload Type : Single SQL Statement
Execution Count : 2
Current Execution : EXEC_9010
Execution Type : TUNE SQL
Scope : COMPREHENSIVE
Time Limit(seconds): 60
Completion Status : COMPLETED
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
Started at : 04/20/2016 09:19:33
Completed at : 04/20/2016 09:20:10
-------------------------------------------------------------------------------
Schema Name: SYS
SQL ID : 5ukykzs1hvk7b
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)
-------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
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: 38.69%)
------------------------------------------
- Consider accepting the recommended SQL profile.
execute dbms_sqltune.accept_sql_profile(task_name => 'test_sql_tuning',
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
task_owner => 'SYS', replace => TRUE);
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original With Adjusted Cost
------------------------------
Plan hash value: 2929971977
--------------------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
--------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | | | 129K (1)| 00:26:00 |
| 1 | SORT AGGREGATE | | 1 | | | | |
| 2 | VIEW | VM_NWVW_2 | 491K| | | 129K (1)| 00:26:00 |
|* 3 | FILTER | | | | | | |
| 4 | HASH GROUP BY | | 491K| 45M| 1067M| 129K (1)| 00:26:00 |
|* 5 | HASH JOIN | | 9837K| 919M| 148M| 45513 (1)| 00:09:07 |
| 6 | TABLE ACCESS FULL| T | 2549K| 119M| | 11886 (1)| 00:02:23 |
| 7 | TABLE ACCESS FULL| T | 2549K| 119M| | 11886 (1)| 00:02:23 |
--------------------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
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
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes |TempSpc| Cost (%CPU)| Time |
-----------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 1 | 116 | | 79651 (1)| 00:15:56 |
| 1 | SORT AGGREGATE | | 1 | 116 | | | |
|* 2 | HASH JOIN | | 1647K| 182M| 148M| 79651 (1)| 00:15:56 |
| 3 | TABLE ACCESS FULL | T | 2549K| 119M| | 11886 (1)| 00:02:23 |
| 4 | VIEW | VW_SQ_1 | 2549K| 162M| | 42760 (1)| 00:08:34 |
| 5 | HASH GROUP BY | | 2549K| 119M| 156M| 42760 (1)| 00:08:34 |
| 6 | TABLE ACCESS FULL| T | 2549K| 119M| | 11886 (1)| 00:02:23 |
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
-----------------------------------------------------------------------------------------
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)")
-------------------------------------------------------------------------------
DBMS_SQLTUNE.REPORT_TUNING_TASK('TEST_SQL_TUNING')
----------------------------------------------------------------------------------------------------
--7.完成后删除sql tunning任务
EXEC DBMS_SQLTUNE.DROP_TUNING_TASK('test_sql_tuning');
--8.查看SQL Tuning Advisor的进展(task执行很久)
col opname for a20
col ADVISOR_NAME for a20
SELECT SID,SERIAL#,USERNAME,OPNAME,ADVISOR_NAME,TARGET_DESC,START_TIME SOFAR, TOTALWORK
FROM V$ADVISOR_PROGRESS
WHERE USERNAME = 'SYS';