Una vez más cuando tenemos problemas de rendimiento cualquier ayuda es poca, Oracle Database ofrece el SQL Access Advisor que nos ayudará ofreciendo recomendaciones para mejora el rendimiento del entorno, indices nuevos, planes de ejecución, etc.. de un SQL Tuning Set (entre otras posibles entradas)
En esta entrada vamos a ver como utilizar el SQL Access Advisor (SAA), que ofrecerá recomendaciones del tipo:
- Particionado de tablas
- Creación de índices
- Creación de vistas materializadas
- Generación de estadisticas.
Que podemos aplicar para mejorar el rendimiento de la BD.
La documentación oficial está aqui.
Partimos de un SQL Tuning Set (STS) creado en la entrada SQL Tuning Set Oracle Database.
- Lo primero que hacemos es crear una access task
El task_id=192 después de la ejecuciónSET SERVEROUTPUT ON DECLARE task_id NUMBER; task_name VARCHAR2(30); BEGIN task_name := 'SH_SAA'; DBMS_ADVISOR.CREATE_TASK(advisor_name=>DBMS_ADVISOR.SQLACCESS_ADVISOR, task_id => task_id, task_name => task_name); DBMS_OUTPUT.PUT_LINE(task_id); END; /
- Configuramos la task
EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER(task_name =>'SH_SAA', parameter=>'TIME_LIMIT', value=>30); EXECUTE DBMS_ADVISOR.SET_TASK_PARAMETER(task_name =>'SH_SAA', parameter=>'ANALYSIS_SCOPE', value=>'ALL');
- Añadimos un SQL Tuning Set «sh_workload» previo a la task, en la «entrada» se explica como crear un SQL Tuning Set
EXECUTE DBMS_ADVISOR.ADD_STS_REF(task_name=>'SH_SAA', sts_owner=>'SYS', workload_name=>'sh_workload');
- Ejecutamos la task
Podemos ver el estado de la ejecución en:exec DBMS_ADVISOR.EXECUTE_TASK (task_name=> 'SH_SAA');
COL TASK_ID FORMAT 999 COL TASK_NAME FORMAT a25 COL STATUS_MESSAGE FORMAT a25 SELECT TASK_ID, TASK_NAME, STATUS, STATUS_MESSAGEFROM USER_ADVISOR_LOG WHERE TASK_NAME='SH_SAA';TASK_ID TASK_NAME STATUS STATUS_MESSAGE ------- ------------------------- ----------- ------------------------- 192 SH_SAA COMPLETED Access advisor execution completed
- Obtención de las recomendaciones
Hay diferentes vistas que no muestran información:DBA_ADVISOR_TASKS, para ver información general de las tasks (documentación):
DBA_ADVISOR_RECOMMENDATIONS, recomendaciones ofrecidas por las tareas (documentación):SET pagesize 1000 SET linesize 200 SELECT TASK_ID,TASK_NAME,STATUS,PCT_COMPLETION_TIME,STATUS_MESSAGE,RECOMMENDATION_COUNT FROM DBA_ADVISOR_TASKS WHERE ADVISOR_NAME = 'SQL Access Advisor' AND TASK_NAME='SH_SAA';TASK_ID TASK_NAME STATUS PCT_COMPLETION_TIME STATUS_MESSAGE RECOMMENDATION_COUNT ------- ------------------------- ----------- ------------------- ------------------------- -------------------- 192 SH_SAA COMPLETED 100 Access advisor execution 2 completed
El campo BENEFIT mostrado en la consulta anterior se refiere a coste del optimizador.SET linesize 200 SELECT REC_ID,RANK,TYPE,BENEFIT FROM DBA_ADVISOR_RECOMMENDATIONS WHERE TASK_NAME='SH_SAA' ORDER BY RANK; REC_ID RANK TYPE BENEFIT ---------- ---------- ------------------------------ ---------- 1 1 ACTIONS 1639905 2 2 ACTIONS 33770
Podemos ver el impacto en las consultas incluidas en el SQL Tuning Set con:
SELECT SQL_ID, REC_ID, PRECOST, POSTCOST, (PRECOST-POSTCOST)*100/PRECOST AS PERCENT_BENEFIT FROM USER_ADVISOR_SQLA_WK_STMTS WHERE TASK_NAME = 'SH_SAA' AND WORKLOAD_NAME = 'sh_workload' ORDER BY percent_benefit DESC; SQL_ID REC_ID PRECOST POSTCOST PERCENT_BENEFIT ------------- ---------- ---------- ---------- --------------- 03ghr9b5m3x43 2 48490 14720 69.6432254 0bg8rg9srv8rm 1 271544 221984 18.2511858 1p5p7drt7atxd 1 247299 202164 18.2511858 1qr4ps69f36jy 1 271544 221984 18.2511858 1xmq1jkcnp2mf 1 252148 206128 18.2511858 1zm0sn3qcx0hu 1 218205 178380 18.2511858 222q8cuf6ugt9 1 227903 186308 18.2511858 28da8t4nc8uk9 1 300638 245768 18.2511858 370m5yqjjcr8z 1 290940 237840 18.2511858 3fgwfcsa2k3bz 1 261846 214056 18.2511858 3zdr12jv606xs 1 256997 210092 18.2511858 416hz7t3mx918 1 203658 166488 18.2511858 4kwqmbh8cs1gp 1 237601 194236 18.2511858 4wazxyxv5cpt0 1 227903 186308 18.2511858 56nj9ptzakm56 1 213356 174416 18.2511858 5hppq6bp5wmnm 1 295789 241804 18.2511858 5vbwrcz3vw3s0 1 295789 241804 18.2511858 6n5rbcc9c9tvs 1 247299 202164 18.2511858 709uggnu40a9a 1 223054 182344 18.2511858 7f6kr3z5p8qxa 1 38792 31712 18.2511858 83wufms0kwjb0 1 38792 31712 18.2511858 8g3y654ptjzrz 1 281242 229912 18.2511858 8hytq9ybsh5xu 1 29094 23784 18.2511858 8k0bufga1dutt 1 43641 35676 18.2511858 8wskn4vvvkd93 1 232752 190272 18.2511858 954q4b1vkp8m4 1 276393 225948 18.2511858 9aft7htmzpd1d 1 324883 265588 18.2511858 9b723qjgkmy9z 1 237601 194236 18.2511858 9fsjrrksxp4gj 1 232752 190272 18.2511858 9h2u2z9y900yk 1 48490 39640 18.2511858 9tkfxkjugywqp 1 53339 43604 18.2511858 9w0c53r5um1xy 1 252148 206128 18.2511858 a75y9uq84au4p 1 184262 150632 18.2511858 a9nt3xdwup082 1 227903 186308 18.2511858 aktx221b6sqc4 1 271544 221984 18.2511858 au7x78c2uju0p 1 300638 245768 18.2511858 c6axjhw2bv23t 1 203658 166488 18.2511858 cmkygw8kypnpb 1 232752 190272 18.2511858 dfdg44tjr89uf 1 232752 190272 18.2511858 fd5j4mmztdpmm 1 38792 31712 18.2511858 fwsw6473mw961 1 227903 186308 18.2511858 fx2c47hcyfz9f 1 38792 31712 18.2511858 gppx8hpcwsb5g 1 33943 27748 18.2511858 gpxukn3ft9qgw 1 53339 43604 18.2511858 gx7ymx5myrd2t 1 261846 214056 18.2511858 08kysb4nyt58n 1 43641 35676 18.2511858 46 rows selected.
DBA_ADVISOR_ACTIONS, cada recomendacion incluye una o más acciones (documentación).
SET linesize 200 COL COMMAND FORMAT a30 SELECT REC_ID,ACTION_ID, COMMAND FROM DBA_ADVISOR_ACTIONS WHERE TASK_NAME='SH_SAA' ORDER BY REC_ID,ACTION_ID; REC_ID ACTION_ID COMMAND ---------- ---------- ------------------------------ 1 1 PARTITION TABLE 1 2 PARTITION TABLE 1 3 PARTITION TABLE 1 4 CREATE MATERIALIZED VIEW LOG 1 6 CREATE MATERIALIZED VIEW LOG 1 8 CREATE MATERIALIZED VIEW LOG 1 10 CREATE MATERIALIZED VIEW 1 11 GATHER TABLE STATISTICS 2 1 PARTITION TABLE 2 2 PARTITION TABLE 2 3 PARTITION TABLE 2 4 CREATE MATERIALIZED VIEW LOG 2 6 CREATE MATERIALIZED VIEW LOG 2 8 CREATE MATERIALIZED VIEW LOG 2 10 CREATE MATERIALIZED VIEW 2 11 GATHER TABLE STATISTICS 2 12 CREATE INDEX 17 rows selected.
Creación de un PL/SQL, esta es la mejor forma de obtener información sobre las recomentaciones ya que facilita la lectura.
CREATE OR REPLACE PROCEDURE show_recm (in_task_name IN VARCHAR2) IS CURSOR curs IS SELECT DISTINCT action_id, command, attr1, attr2, attr3, attr4 FROM user_advisor_actions WHERE task_name = in_task_name ORDER BY action_id; v_action number; v_command VARCHAR2(32); v_attr1 VARCHAR2(4000); v_attr2 VARCHAR2(4000); v_attr3 VARCHAR2(4000); v_attr4 VARCHAR2(4000); v_attr5 VARCHAR2(4000); BEGIN OPEN curs; DBMS_OUTPUT.PUT_LINE('========================================='); DBMS_OUTPUT.PUT_LINE('Task_name = ' || in_task_name); LOOP FETCH curs INTO v_action, v_command, v_attr1, v_attr2, v_attr3, v_attr4 ; EXIT when curs%NOTFOUND; DBMS_OUTPUT.PUT_LINE('Action ID: ' || v_action); DBMS_OUTPUT.PUT_LINE('Command : ' || v_command); DBMS_OUTPUT.PUT_LINE('Attr1 (name) : ' || SUBSTR(v_attr1,1,30)); DBMS_OUTPUT.PUT_LINE('Attr2 (tablespace): ' || SUBSTR(v_attr2,1,30)); DBMS_OUTPUT.PUT_LINE('Attr3 : ' || SUBSTR(v_attr3,1,30)); DBMS_OUTPUT.PUT_LINE('Attr4 : ' || v_attr4); DBMS_OUTPUT.PUT_LINE('Attr5 : ' || v_attr5); DBMS_OUTPUT.PUT_LINE('----------------------------------------'); END LOOP; CLOSE curs; DBMS_OUTPUT.PUT_LINE('=========END RECOMMENDATIONS============'); END show_recm; /
Llamamos al PL/SQL para ver las recomendaciones:
SET SERVEROUTPUT ON SIZE 99999 exec show_recm('SH_SAA'); ========================================= Task_name = SH_SAA Action ID: 1 Command : PARTITION TABLE Attr1 (name) : "SH"."SALES" Attr2 (tablespace): Attr3 : ("TIME_ID") Attr4 : HASH Attr5 : ---------------------------------------- Action ID: 2 Command : PARTITION TABLE Attr1 (name) : "SH"."CUSTOMERS" Attr2 (tablespace): Attr3 : ("CUST_ID") Attr4 : INTERVAL Attr5 : ---------------------------------------- Action ID: 3 Command : PARTITION TABLE Attr1 (name) : "SH"."TIMES" Attr2 (tablespace): Attr3 : ("TIME_ID") Attr4 : HASH Attr5 : ---------------------------------------- Action ID: 4 Command : CREATE MATERIALIZED VIEW LOG Attr1 (name) : "SH"."TIMES" Attr2 (tablespace): Attr3 : ROWID, SEQUENCE Attr4 : INCLUDING NEW VALUES Attr5 : ---------------------------------------- Action ID: 6 Command : CREATE MATERIALIZED VIEW LOG Attr1 (name) : "SH"."SALES" Attr2 (tablespace): Attr3 : ROWID, SEQUENCE Attr4 : INCLUDING NEW VALUES Attr5 : ---------------------------------------- Action ID: 8 Command : CREATE MATERIALIZED VIEW LOG Attr1 (name) : "SH"."CUSTOMERS" Attr2 (tablespace): Attr3 : ROWID, SEQUENCE Attr4 : INCLUDING NEW VALUES Attr5 : ---------------------------------------- Action ID: 10 Command : CREATE MATERIALIZED VIEW Attr1 (name) : "SYS"."MV$$_00C00000" Attr2 (tablespace): Attr3 : REFRESH FAST WITH ROWID Attr4 : ENABLE QUERY REWRITE Attr5 : ---------------------------------------- Action ID: 11 Command : GATHER TABLE STATISTICS Attr1 (name) : "SYS"."MV$$_00C00000" Attr2 (tablespace): Attr3 : -1 Attr4 : Attr5 : ---------------------------------------- Action ID: 12 Command : CREATE INDEX Attr1 (name) : "SYS"."MV$$_00C00000_IDX$$_00C Attr2 (tablespace): Attr3 : "SYS"."MV$$_00C00000" Attr4 : BITMAP Attr5 : ---------------------------------------- =========END RECOMMENDATIONS============ PL/SQL procedure successfully completed.
Podemos crear un script que implemente las recomentaciones con:
CREATE DIRECTORY ADVISOR_RESULTS AS '/tmp'; GRANT READ ON DIRECTORY ADVISOR_RESULTS TO PUBLIC; GRANT WRITE ON DIRECTORY ADVISOR_RESULTS TO PUBLIC; EXECUTE DBMS_ADVISOR.CREATE_FILE(DBMS_ADVISOR.GET_TASK_SCRIPT('SH_SAA'),'ADVISOR_RESULTS', 'sql_access_advisor_script.sql');
Os dejo el resultado del sql_access_advisor_script.sql.
Suerte…