Recently, a co-worker encountered a significant performance hurdle after a database upgrade. The plan included verifying object integrity using analyze table <tablename> validate structure cascade. While most tables processed quickly, one specific table appeared to hang.
After killing the job and analyzing objects individually, they found the culprit: a single index.
When asked how long the process had been running, the answer was shocking: three days. A 10046 trace revealed the process was consumed by db file sequential read events on the table.
The root cause? Clustering Factor.
The analyze index process verifies every row. If the table is well-ordered (clustered) according to the index, the number of blocks read will be close to the actual block count of the table. However, if the table is poorly ordered, the system may read the same blocks from disk millions of times as it "walks" the index.
Consider rows with IDs 1 through 5.
| ID | Block Number |
| 1 | 22 |
| 2 | 75 |
| 3 | 16 |
| 4 | 2 |
| 5 | 104 |
In this case 5 separate blocks must be read to retrieve these rows. In the course of walking the index, some minutes later these rows must also be read:
| ID | Block Number |
| 1048576 | 22 |
| 1048577 | 75 |
| 1048578 | 16 |
| 1048579 | 2 |
| 1048580 | 104 |
Later, when the index reaches IDs 1048576 through 1048580, it may need those same blocks again. By then, they've likely been aged out of the cache, forcing yet another physical disk read.
To see how bad this can get, we ran a test with $10^7$ (10 million) rows.
-- 1e3 x 1e4 = 1e7 rows def level_1=1e3 def level_2=1e4 create table validate_me pctfree 0 as select -- floor(dbms_random.value(1,1e6)) id, -- For bad clustering factor rownum id, -- For good clustering factor substr('ABCDEFGHIJKLMNOPQRSTUVWXYZ',mod(rownum,10),15) search_data, rpad('x',100,'x') padded_data from (select null from dual connect by level <= &level_1) a, (select null from dual connect by level <= &level_2) b; create index validate_me_idx1 on validate_me(id, search_data);
Using a custom script to check the clustering factor, we see that for a poorly ordered table, the factor is nearly equal to the number of rows:
TABLE NAME TABLE ROWS INDEX NAME LEAF BLOCKS CLUSTERING FACTOR ----------- ----------- --------------- ----------- ----------------- VALIDATE_ME 10,000,000 VALIDATE_ME_IDX1 45,346 10,160,089
The validation results were stark:
By analyzing the 10046 trace, we can see exactly how many times each block was visited.
Using command-line tools like awk, sort, and uniq, we verified that in a well-ordered table, no block was read more than once
$> tail -n +64 trace.trc | grep "db file sequential read" | awk '{ print $10 }' | sort | uniq -c | sort -n | tail 1 743000 1 743001 1 743002
In contrast, for the poorly ordered table, the most active blocks were read 53 to 55 times each
$> tail -n +51 trace.trc | grep "db file sequential read" | awk '{ print $10 }' | sort | uniq -c | sort -n | tail -5 54 635330 55 523616 55 530064 55 626066 55 680250
If your goal is to find block corruption or ensure integrity, analyze index validate structure may be the most expensive way to do it.
RMAN can check for physical and logical corruption across the entire database without the overhead of walking every index entry
RMAN> backup check logical validate database;
In our test, RMAN validated the entire database in just 25 minutes—significantly faster than the 46 minutes spent on a single large index.
If you suspect an index is corrupt, it is often more efficient to simply rebuild it. On Enterprise Edition, this can be done online
SQL> alter index validate_me_idx1 rebuild online; -- Elapsed: 00:00:59.88
Creating the index took 28 seconds and the rebuild took 60 seconds. Both are vastly superior to waiting 40 minutes (or three days) for validation.
The conclusion is clear: use analyze index validate structure with extreme caution on large indexes. The resource intensity and time required often outweigh the benefits when faster alternatives like RMAN or index rebuilds exist.
Ready to optimize your Oracle Database for the future?