这种方式是很明确的一组sql的优化时,可以使用,但是感觉还是sqlcache的傻瓜式优化更实惠
create table testobj as select * from dba_objects;
exec dbms_stats.gather_table_stats(ownname => 'TEST',tabname => 'TESTOBJ',cascade => true);
DECLARE
l_taskname VARCHAR2(30) := 'test_sql_access_task';
l_task_desc VARCHAR2(128) := 'Test SQL Access Task';
l_wkld_name VARCHAR2(30) := 'test_work_load';
l_saved_rows NUMBER := 0;
l_failed_rows NUMBER := 0;
l_num_found NUMBER;
sql_text varchar2(400);
BEGIN
-- Create an SQLAccess Advisor task.
DBMS_ADVISOR.create_task(advisor_name => DBMS_ADVISOR.sqlaccess_advisor,
task_name => l_taskname,
task_desc => l_task_desc);
-- Reset the task.
DBMS_ADVISOR.reset_task(task_name => l_taskname);
-- Create a workload.
SELECT COUNT(*)
INTO l_num_found
FROM user_advisor_sqlw_sum
WHERE workload_name = l_wkld_name;
IF l_num_found = 0 THEN
DBMS_ADVISOR.create_sqlwkld(workload_name => l_wkld_name);
END IF;
-- Link the workload to the task.
SELECT count(*)
INTO l_num_found
FROM user_advisor_sqla_wk_map
WHERE task_name = l_taskname
AND workload_name = l_wkld_name;
IF l_num_found = 0 THEN
DBMS_ADVISOR.add_sqlwkld_ref(task_name => l_taskname,
workload_name => l_wkld_name);
END IF;
-- Set workload parameters.
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'ACTION_LIST',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'MODULE_LIST',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'SQL_LIMIT',
DBMS_ADVISOR.ADVISOR_UNLIMITED);
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'ORDER_LIST',
'PRIORITY,OPTIMIZER_COST');
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'USERNAME_LIST',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_sqlwkld_parameter(l_wkld_name,
'VALID_TABLE_LIST',
DBMS_ADVISOR.ADVISOR_UNUSED);
--
/* DBMS_ADVISOR.import_sqlwkld_sqlcache(l_wkld_name,
'REPLACE',
2,
l_saved_rows,
l_failed_rows);
*/
/* select * from testobj where OBJECT_ID=16;
select * from testobj where OBJECT_NAME like 'OBJ%';*/
sql_text := 'select * from testobj where OBJECT_ID=16';
dbms_advisor.add_sqlwkld_statement(workload_name => l_wkld_name,
module => 'MONTHLY',
action => 'ROLLUP',
cpu_time => 0,
elapsed_time => 0,
disk_reads => 0,
buffer_gets => 0,
rows_processed => 0,
optimizer_cost => 0,
executions => 1,
priority => 2,
last_execution_date => SYSDATE,
stat_period => 0,
username => 'TEST',
sql_text => sql_text);
sql_text := 'select * from testobj where OBJECT_NAME like ''OBJ%''';
dbms_advisor.add_sqlwkld_statement(workload_name => l_wkld_name,
module => 'MONTHLY',
action => 'ROLLUP',
cpu_time => 0,
elapsed_time => 0,
disk_reads => 0,
buffer_gets => 0,
rows_processed => 0,
optimizer_cost => 0,
executions => 1,
priority => 2,
last_execution_date => SYSDATE ,
stat_period => 0,
username => 'TEST',
sql_text => sql_text);
-- Set task parameters.
DBMS_ADVISOR.set_task_parameter(l_taskname,
'_MARK_IMPLEMENTATION',
'FALSE');
DBMS_ADVISOR.set_task_parameter(l_taskname,
'EXECUTION_TYPE',
'INDEX_ONLY');
DBMS_ADVISOR.set_task_parameter(l_taskname, 'MODE', 'COMPREHENSIVE');
DBMS_ADVISOR.set_task_parameter(l_taskname,
'STORAGE_CHANGE',
DBMS_ADVISOR.ADVISOR_UNLIMITED);
DBMS_ADVISOR.set_task_parameter(l_taskname, 'DML_VOLATILITY', 'TRUE');
DBMS_ADVISOR.set_task_parameter(l_taskname,
'ORDER_LIST',
'PRIORITY,OPTIMIZER_COST');
DBMS_ADVISOR.set_task_parameter(l_taskname, 'WORKLOAD_SCOPE', 'PARTIAL');
DBMS_ADVISOR.set_task_parameter(l_taskname,
'DEF_INDEX_TABLESPACE',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_task_parameter(l_taskname,
'DEF_INDEX_OWNER',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_task_parameter(l_taskname,
'DEF_MVIEW_TABLESPACE',
DBMS_ADVISOR.ADVISOR_UNUSED);
DBMS_ADVISOR.set_task_parameter(l_taskname,
'DEF_MVIEW_OWNER',
DBMS_ADVISOR.ADVISOR_UNUSED);
-- Execute the task.
DBMS_ADVISOR.execute_task(task_name => l_taskname);
END;
/
SQL>
SQL> SET LONG 100000
SQL> SET PAGESIZE 50000
SQL> SELECT DBMS_ADVISOR.get_task_script('test_sql_access_task') AS script FROM dual;
SCRIPT
--------------------------------------------------------------------------------
Rem SQL 访问指导: 版本 18.0.0.0.0 - 正式版
Rem
Rem 用户名: TEST
Rem 任务: test_sql_access_task
Rem 执行日期:
Rem
CREATE INDEX "TEST"."TESTOBJ_IDX$$_00370000"
ON "TEST"."TESTOBJ"
("OBJECT_NAME")
COMPUTE STATISTICS;
CREATE INDEX "TEST"."TESTOBJ_IDX$$_00370001"
ON "TEST"."TESTOBJ"
("OBJECT_ID")
COMPUTE STATISTICS;
SQL>
SQL> select a.owner,
2 a.task_id,
3 a.task_name,
4 execution_start,
5 a.status_message,
6 b.command
7 from dba_advisor_log a, dba_advisor_actions b
8 where a.task_id = b.task_id
9 and b.task_name = 'test_sql_access_task';
OWNER TASK_ID TASK_NAME EXECUTION_START STATUS_MESSAGE COMMAND
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------- -------------------------------------------------------------------------------- ----------------------------------------------------------------
TEST 55 test_sql_access_task 2018/12/14 8:23 访问指导执行完毕 CREATE INDEX
TEST 55 test_sql_access_task 2018/12/14 8:23 访问指导执行完毕 CREATE INDEX
SQL> SELECT sql_id,
2 precost 优化前cost,
3 postcost 优化后cost,
4 (precost / postcost) cost提升倍数,decode(PRIORITY, 1, '高', 2, '中', 3, '低') 重要性
5 FROM dba_advisor_sqla_wk_stmts
6 WHERE task_name = 'test_sql_access_task';
SQL_ID 优化前COST 优化后COST COST提升倍数 重要性
------------- ---------- ---------- ------------ ------
3gc62uk6vc0pu 389 3 129.66666666 中
at46bsa12zx0a 389 5 77.8 中
exec dbms_advisor.delete_task('test_sql_access_task');