SQL访问顾问SAA(SQL Access Advisor)针对多条sql优化实践之一:从SQL Cache中加载

看过这个的同行,请点赞、关注本博客

create table testobj as select * from dba_objects;

exec dbms_stats.gather_table_stats(ownname => 'TEST',tabname => 'TESTOBJ',cascade => true); 

一、加载sql进入sqlcache

SQL访问顾问SAA(SQL Access Advisor)针对多条sql优化实践之一:从SQL Cache中加载_第1张图片

二、 saa从sqlcache加载分析,开始执行任务


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;
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);
  -- 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;
/

  DBMS_ADVISOR.import_sqlwkld_sqlcache(l_wkld_name,
                                       'REPLACE',
                                       2,
                                       l_saved_rows,
                                       l_failed_rows);这个属于sqlcache加载;

参考:

加载SQL Cache工作量
可以使用dbms_advisor.import_sqlwkld_sqlcache过程来获得SQL Cache工作量。在调用这个过程的 时候,SQL Cache中的当前内容将会被分析并且加载到工作量中。 dbms_advisor.import_sqlwkld_sqlcache过程从SQL Cache中加载SQL工作量,语法如下:

dbms_advisor.import_sqlwkld_sqlcache (
workload_name in varchar2,
import_mode in varchar2,
priority in number := 2,
saved_rows out number,
failed_rows out number);

下面的例子从SQL Cache中加载之前创建的工作量MYWORKLOAD。加载工作量语句的优先级为2:

variable saved_stmts number;
variable failed_stmts number;
execute dbms_advisor.import_sqlwkld_sqlcache('MYWORKLOAD', 'APPEND', 2, :saved_stmts,  :failed_stmts);

SQL Access Advisor可以从SQL Cache中检索工作量信息。如果收集的数据是从实例参数 cursor_sharing设置为similar或force的服务器中所检索到的,那么使用文本值的查询将会被转换为 包含系统生成变量的语句。如果使用SQL Access Advisor来建议物化视图,那么服务器应该将参数 cursor_sharing设置为exact,因此有where子句的物化视图会被建议。

三、查看分析建议

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$$_002D0000"
    ON "TEST"."TESTOBJ"
    ("OBJECT_NAME")
    COMPUTE STATISTICS;
CREATE INDEX "TEST"."TESTOBJ_IDX$$_002D0001"
    ON "TEST"."TESTOBJ"
    ("OBJECT_ID")
    COMPUTE STATISTICS;

四、查看分析提高情况,提高有改善的两个sqlid就是对应的两个create index之后的sql的

SQL> select a.owner,
  2  a.task_id,
  3  a.task_name,
  4  execution_start,
  5  a.status_message,
  6  b.command from dba_advisor_log a,
  7  dba_advisor_actions b where a.task_id = b.task_id and b.task_name = 'test_sql_access_task';
OWNER                                                                               TASK_ID TASK_NAME                                                                        EXECUTION_START STATUS_MESSAGE                                                                   COMMAND
-------------------------------------------------------------------------------- ---------- -------------------------------------------------------------------------------- --------------- -------------------------------------------------------------------------------- ----------------------------------------------------------------
TEST                                                                                     45 test_sql_access_task                                                             2018/12/13 16:2 访问指导执行完毕                                                                 CREATE INDEX
TEST                                                                                     45 test_sql_access_task                                                             2018/12/13 16:2 访问指导执行完毕                                                                 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
  7  task_name='test_sql_access_task';
SQL_ID           优化前COST    优化后COST     COST提升倍数 重要性
------------- ---------- ---------- ------------ ------
3qpb0nj36qxvs         45         45            1 中
bsxmbc4z76ry5        391        391            1 中
31j9fzrraqs2m        389          5         77.8 中
1hv9axpnydt07         12         12            1 中
16km2m1f85nk5         45         45            1 中
agffxdv97kvp7         30         30            1 中
2dxcvzt5phbz2        297        297            1 中
2vn85au9ffaun        389          3 129.66666666 中
320mymhry8p1v         48         48            1 中
2pkf91r1mcd6w         21         21            1 中
at2h5x34yj2c4         24         24            1 中
cs5wf87un48p9         99         99            1 中
12 rows selected

这个太牛叉了,感觉可以傻瓜式的应用于生产中,随时检查,傻瓜式优化

五、别忘了删除

 exec dbms_advisor.delete_task('test_sql_access_task');

 

你可能感兴趣的:(SQL访问顾问SAA(SQL Access Advisor)针对多条sql优化实践之一:从SQL Cache中加载)