Тествано на 11.2.0.2
SQL tunning advisor е страшна далавера. Е, изисква допълнителен лиценз за tunning pack, но върши работа, която за обикновен човек е практически невъзможна.
По-честият вариант е когато нещо се скапе в production и трябва спешно да се оправи. Ех, колко пъти ни е спасявал SQL tunning advisor в такива ситуации… Хем намира решение (без да ти се налага да разбираш какво, аджеба, прави тази заявка); хем прави профил – така не се налага промяна в кода на самото приложение. Аз лично не съм се и опитвал ръчно да правя профил, супер пипкава работа ми изглежда. Правил съм ръчно outline и това беше пипкаво.
Има, обаче, и един друг сценарий. Представете си един горд developer, който е сътворил заявка с 97 реда execution plan. И моли за съдействие при оптимизацията. Това нещо е извън възможностите за възприемане. А SQL tunning advisor минава за минути и в повечето случаи наистина дава добри идеи. Как да го пуснеш, обаче?
През Grid/Cloud control е лесно – цъкаш, цъкаш и става. Но какво парим, ако го няма Could control закачен към базата? Или ако просто искаме да видим някой съвет за едно query, което ни мъчи?
Всъщност става много лесно:
1. Създаване на таск:
DECLARE
v_task VARCHAR2(30);
v_sql CLOB;
BEGIN
v_sql := 'SELECT ... FROM ... WHERE ...';
v_task := DBMS_SQLTUNE.CREATE_TUNING_TASK(sql_text => v_sql,
user_name => 'HR',
scope => 'COMPREHENSIVE',
time_limit => 3600, -- seconds
task_name => 'tune_test2',
description => 'Tune statement used for the new XYZ functionality.');
END;
/
2. Изпълнение. Това може да отнеме доста време, в зависимост от сложността на заявката и зададения лимит:
exec dbms_sqltune.execute_tuning_task(task_name => 'tune_test2');
3. Да видим резултата. Това е целта, всъщност
set long 90000 longchunksize 90000
set linesize 232 pagesize 9999
select dbms_sqltune.report_tuning_task('tune_test2') from dual;
DBMS_SQLTUNE.REPORT_TUNING_TASK('TUNE_TEST2')
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
GENERAL INFORMATION SECTION
-------------------------------------------------------------------------------
Tuning Task Name : tune_test2
Tuning Task Owner : HR
Workload Type : Single SQL Statement
Scope : COMPREHENSIVE
Time Limit(seconds): 3600
Completion Status : COMPLETED
Started at : 10/05/2012 12:07:10
Completed at : 10/05/2012 12:12:13
-------------------------------------------------------------------------------
Schema Name: HR
SQL ID : ba6g55fakh01v
SQL Text : SELECT ...
-------------------------------------------------------------------------------
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: 76.48%)
------------------------------------------
- Consider accepting the recommended SQL profile.
execute dbms_sqltune.accept_sql_profile(task_name => 'tune_test2',
task_owner => 'HR', replace => TRUE);
-------------------------------------------------------------------------------
EXPLAIN PLANS SECTION
-------------------------------------------------------------------------------
1- Original With Adjusted Cost
------------------------------
Plan hash value: 2801951464
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 21 | 1302 | 30711 (4)| 00:06:09 |
...
| 97 | TABLE ACCESS FULL | MY_TAB | 2 | 10 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
...
95 - access("E"."TEST_ID"="T"."TEST_ID")
2- Original With Adjusted Cost
------------------------------
-------------------------------------------------------------------------------
Error: cannot fetch explain plan for object: 1
-------------------------------------------------------------------------------
3- Using SQL Profile
--------------------
Plan hash value: 3439552619
------------------------------------------------------------------------------------------------------------------------
| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
------------------------------------------------------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 21 | 1302 | 7223 (2)| 00:01:27 |
....
| 97 | TABLE ACCESS FULL | MY_TAB | 2 | 10 | 2 (0)| 00:00:01 |
------------------------------------------------------------------------------------------------------------------------
Predicate Information (identified by operation id):
---------------------------------------------------
....
95 - access("E"."TEST_ID"="T"."TEST_ID")
(Да, наистина го пусках това за заявка с 97 стъпки в плана и 95 филтъра. Естествено тук съм отрязал както заявката, така и плановете и предикатите )
4. Може и да приложим предложения план. Аз в случая исках само да видя съвета, но пък за да се измери реалната промяна, трябва да се тества наистина с пускане на заявката
execute dbms_sqltune.accept_sql_profile(task_name => 'tune_test2', task_owner => 'HR', replace => TRUE);