Recently I had faced one performance issue related to DB statistics.
Suddenly we have got CPU spike on database and found a query causing the CPU spike.
Finally I started to Investigate.
This query have joined three tables and all the tables have a partition
- All the tables have statistics Upto date and weekend job gathered the stats.
- No Fragmentation/No execution plan changed.
- No blocking locks/No concurrent access on these tables.
Finally I got the issue,
This query is accessing the current partition data (Daily Partition) for every 20 minutes through job.
The daily partition loading the data and at the same time transaction query can try to access the real time data.
Normally current daily partition doesn’t have any statistics, at the end of day/weekend gathered the statistics based on Application needs. Even if gathered the stats before they days starts it will be “ZERO” rows doesn’t help to optimizer to improve the query performance.
Already I had faced the same stats issue on partition few years ago, so i have copied the stats from existing partition (good stats) to current partition and fixed the issue.
Oops …But today issue was happened on oracle 9i.
There is No DBMS_STATS.COPY_TABLE_STATS feature in oracle 9i.
But We can manually set the STATS on tables/partitions using below procedure.
Syntax
DBMS_STATS.SET_TABLE_STATS (
ownname VARCHAR2,
tabname VARCHAR2,
partname VARCHAR2 DEFAULT NULL,
stattab VARCHAR2 DEFAULT NULL,
statid VARCHAR2 DEFAULT NULL,
numrows NUMBER DEFAULT NULL,
numblks NUMBER DEFAULT NULL,
avgrlen NUMBER DEFAULT NULL,
flags NUMBER DEFAULT NULL,
statown VARCHAR2 DEFAULT NULL,
no_invalidate BOOLEAN DEFAULT to_no_invalidate_type (
get_param('NO_INVALIDATE')),
cachedblk NUMBER DEFAULT NULL,
cachehit NUMBER DEFUALT NULL,
force BOOLEAN DEFAULT FALSE);
Finally I had found good stats on one partition and manually set it for current partition using below procedure.
exec dbms_stats.set_table_stats (ownname => ‘ARUL’, tabname=>’ARUL_TEST’,partname=>’ARULTEST_DP201313’,numrows=> 145667907, numblks=>568066,avgrlen=> 150);
I have scheduled a job after my weekend completed, and its set the stats for next one week partitions and this query is running fine.