Imagine this. You get a call. A specific SQL statement is running slow today, and the statement was running fine yesterday.
You quickly review the SQL statement, apply the steps from my
troubleshooting guide, and determine the cause of the slowness is an execution plan change.
What is your next question?
I would ask, why did the plan change?
Most of the times, the plan change is caused by new statistics in the
database. Wouldn’t it be awesome to determine quickly if the stats have changed, and what exactly has changed?
Of course it would!
Last week we discussed that anytime you gather new statistics, the current set of stats is saved in the SYSAUX tablespace in the WRI$% tables.
Oracle provides a tool to compare the current statistics with the ones saved in the history. You can also compare the current statistics with statistics saved in the stat table, or with pending statistics
(stats that were gathered but not published yet).
To run the comparison, you need to use dbms_stats package.
Let’s see how this works.
The test case is setup on the SCOTT.EMP table. Stats were gathered a few times on the table, as you will see in the
example.
When you want to compare the stats with previous ones, you need to provide the timestamps for the comparison. Usually time1 is the current time, and time2 is the point in time in the past, you do the comparison against.
However both time1 and time2 could be in the past.
This process, involves 2
steps. First find out what statistics you have available, and second, do the comparison.
Let’s see it in action!
1. Check the availability of the stats for the table: (hint, query dba_tab_stats_history)
select table_name,stats_update_time from dba_tab_stats_history
where owner='SCOTT' and
table_name='EMP';
TABLE_NAME STATS_UPDATE_TIME
--------------- -------------------------------------
EMP 28-NOV-17 07.38.41.840467 PM -08:00
EMP 28-NOV-17 07.47.19.102063 PM -08:00
2. Compare the stats: (hint, use dbms_stats.diff_table_stats_in_history)
set long 2000000
set pagesize 1000
select * from table(dbms_stats.diff_table_stats_in_history(
ownname => 'SCOTT',
tabname => 'EMP',
time1 => systimestamp,
time2 => to_timestamp('28-NOV-17 07.47.19 PM','DD-MON-YY hh12.mi.ss AM'),
pctthreshold => 0));