Sei sulla pagina 1di 5

Report Prepared for

Mail Online
From NCS London
Prepared by Saurabh Penkar

5/16/2013

SCRIPT TO IDENTIFY SQL WITH BAD PLAN


The script below identifies SQL with bad plan for last 5 hours by using snap id.
set lines 155 col execs for 999,999,999 col min_etime for 999,999.99 col max_etime for 999,999.99 col avg_etime for 999,999.999 col avg_lio for 999,999,999.9 col norm_stddev for 999,999.9999 col begin_interval_time for a30 col node for 99999 break on plan_hash_value on startup_time skip 1 select * from ( select sql_id, sum(execs), min(avg_etime) min_etime, max(avg_etime) max_etime, stddev_etime/min(avg_etime) norm_stddev from ( select sql_id, plan_hash_value, execs, avg_etime, stddev(avg_etime) over (partition by sql_id) stddev_etime from ( select sql_id, plan_hash_value, sum(nvl(executions_delta,0)) execs, (sum(elapsed_time_delta)/decode(sum(nvl(executions_delta,0)),0,1,sum(executions_delta)) /1000000) avg_etime -- sum((buffer_gets_delta/decode(nvl(buffer_gets_delta,0),0,1,executions_delta))) avg_lio from DBA_HIST_SQLSTAT S, DBA_HIST_SNAPSHOT SS where ss.snap_id = S.snap_id and ss.instance_number = S.instance_number and executions_delta > 0 and ss.snap_id > (select max(snap_id) -5 from DBA_HIST_SNAPSHOT) group by sql_id, plan_hash_value ) ) group by sql_id, stddev_etime ) where norm_stddev > 2 and max_etime > 1 order by max_etime desc /

Note: The above query Identifies Sqls with bad plan across all schemas. The script is saved on MOL production Server in the /ncs/scripts folder with the name of unstable_plan.sql Sample OUTPUT:
SQL_ID cz902akhwp9hj 898udb5mj0szp SUM(EXECS) 1720 347 MIN_ETIME .70 .02 MAX_ETIME 14.39 .52 NORM_STDDEV 13.7788 18.3872 ------------- ---------- ----------- ----------- -------------

How to check Good or Bad Plan A script is available at MOL Production Server in /ncs/scripts folder with the name of awr_plan_change.sql
SQL> @awr_plan_change Enter value for sql_id: cz902akhwp9hj old new 6: where sql_id = nvl('&sql_id','4dqs2k5tynk61') 6: where sql_id = nvl('cz902akhwp9hj','4dqs2k5tynk61')

SNAP_ID 59812 59812 59813 59814 59814 59815 59816 59817 59818

NODE BEGIN_INTERVAL_TIME 2 18-JUN-13 02.00.02.615 2 18-JUN-13 02.00.02.615 2 18-JUN-13 03.00.11.191 1 18-JUN-13 04.00.14.891 2 18-JUN-13 04.00.15.087 2 18-JUN-13 05.00.01.844 2 18-JUN-13 06.00.05.740 2 18-JUN-13 07.00.09.836 2 18-JUN-13 08.00.13.786

SQL_ID cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj cz902akhwp9hj

PLAN_HASH_VALUE 3907475297 3251602150 3907475297 3251602150 3907475297

EXECS 46 4 87 101 90 71 121 108 73

AVG_ETIME 24.700 .364 14.821 .546 12.116 17.405 16.514 10.069 13.606

AVG_LIO 1,270,465.9 12,943.5 890,528.8 21,321.9 819,684.7 1,177,575.4 1,023,555.0 677,803.2 848,866.1

-------- ------ ----------------------- ------------- --------------- -------- ------------ ------------

The Yellow highlighted plan hash value is the good plan as it is using less Avg Estimated time and Avg I/O. Comparatively the red highlighted plan is using higher Avg Estimated time and Avg I/O. The bad plan is active so we will flush it off for performance improvement. Getting Plan Hash Value and Address from V$SQL SELECT sql_id, hash_value, plan_hash_value, address FROM v$sqlarea where sql_id='cz902akhwp9hj '; OUTPUT:
SQL_ID HASH_VALUE PLAN_HASH_VALUE ADDRESS 3907475297 0000000879AC90C8 ------------- ---------- --------------- ---------------cz902akhwp9hj 2624412763

Setting Session Event ALTER SESSION SET EVENTS '5614566 trace name context forever'; Running Procedure to purge the query from shared pool Here we need to provide the Address and the plan_hash_value from the above query to purge bad plan. exec dbms_shared_pool.purge(0000000879AC90C8, 3907475297,'C'); Check Bad plan is flushed or not It gives you information about the difference in address value for both nodes. SQL> SELECT inst_id, sql_id, hash_value, plan_hash_value, address FROM gv$sqlarea WHERE sql_id='cz902akhwp9hj'; Sample Ouput:
INST_ID SQL_ID HASH_VALUE PLAN_HASH_VALUE ADDRESS 3251602150 000000087EA5D068 0000000879AC90C8 ---------- ------------- ---------- --------------- ---------------1 cz902akhwp9hj 2714412561 2 cz902akhwp9hj 2714412561

Appendix Script Type 2: set col col col col col lines 155 execs for 999,999,999 min_etime for 999,999.99 max_etime for 999,999.99 avg_etime for 999,999.999 avg_lio for 999,999,999.9

col norm_stddev for 999,999.9999 col begin_interval_time for a30 col node for 99999 break on plan_hash_value on startup_time skip 1 select * from ( select sql_id, sum(execs), min(avg_etime) min_etime, max(avg_etime) max_etime, stddev_etime/min(avg_etime) norm_stddev from ( select sql_id, plan_hash_value, execs, avg_etime, stddev(avg_etime) over (partition by sql_id) stddev_etime from ( select sql_id, plan_hash_value, sum(nvl(executions_delta,0)) execs, (sum(elapsed_time_delta)/decode(sum(nvl(executions_delta,0)),0,1,sum(executions _delta))/1000000) avg_etime -sum((buffer_gets_delta/decode(nvl(buffer_gets_delta,0),0,1,executions_delta))) avg_lio from DBA_HIST_SQLSTAT S, DBA_HIST_SNAPSHOT SS where ss.snap_id = S.snap_id and ss.instance_number = S.instance_number and S.parsing_schema_name = '&parsing_schema_name' and executions_delta > 0 and ss.snap_id > (select max(snap_id) -5 from DBA_HIST_SNAPSHOT) group by sql_id, plan_hash_value ) ) group by sql_id, stddev_etime ) where norm_stddev > 2 and max_etime > 1 order by max_etime desc / Note: Need to provide Schema name.

Potrebbero piacerti anche