Optimizer statistics are one of the most important components of Oracle Database performance tuning.
Oracle’s Cost-Based Optimizer (CBO) depends heavily on accurate statistics to generate efficient execution plans.
In this blog, we will explore:
- What table statistics are
- Why statistics matter
- What GRANULARITY means in DBMS_STATS
- How GATHER_TABLE_STATS works
- Understanding DEGREE parameter
- Reading DBA_TAB_STATISTICS
- Analyzing real output from Oracle Autonomous Database
Gathering Table Statistics
The following command was executed:
SQL> exec dbms_stats.gather_table_stats(
'TEST_USER',
'TAB1',
degree=>4,
granularity=>'ALL'
)
Output:
PL/SQL procedure successfully completed.
What Does GATHER_TABLE_STATS Do?
The procedure:
DBMS_STATS.GATHER_TABLE_STATS
collects optimizer statistics for a table.
These statistics help Oracle understand:
- How many rows exist
- How much storage is used
- Average row size
- Data distribution
- Whether statistics are stale
- How expensive a query may be
Oracle’s optimizer uses this information to choose:
- Index scans
- Full table scans
- Hash joins
- Nested loops
- Parallel execution plans
Understanding the Parameters
1. Schema Name
'TEST_USER'
This is the schema owner.
2. Table Name
'TAB1'
The target table whose statistics will be gathered.
3. DEGREE => 4
degree=>4
This enables parallelism during statistics gathering.
Oracle can use:
- 4 parallel execution workers
to scan the table faster.
This is especially useful for:
- Large tables
- Data warehouse systems
- Partitioned tables
- High-volume analytics
4. GRANULARITY => 'ALL'
granularity=>'ALL'
This is one of the most important parts of the command.
GRANULARITY determines:
At which levels Oracle gathers statistics.
What Does GRANULARITY Mean?
For partitioned tables, Oracle can gather statistics at multiple levels:
- Global level
- Partition level
- Subpartition level
The GRANULARITY parameter controls which levels are analyzed.
Common GRANULARITY Options
| Granularity | Meaning |
|---|---|
| AUTO | Oracle decides automatically |
| GLOBAL | Only global table statistics |
| PARTITION | Only partition statistics |
| SUBPARTITION | Only subpartition statistics |
| ALL | Global + Partition + Subpartition statistics |
What Happens with GRANULARITY='ALL'?
When using:
granularity=>'ALL'
Oracle gathers:
- Table-level statistics
- Partition-level statistics
- Subpartition-level statistics
if the table is partitioned.
For non-partitioned tables, Oracle simply gathers normal table statistics.
Checking Row Count
The table contains:
SQL> select count(*) from test_user.tab1; COUNT(*) -------- 93743
This confirms:
- 93,743 rows exist in the table
Understanding DBA_TAB_STATISTICS
Oracle stores optimizer statistics metadata in:
DBA_TAB_STATISTICS
This view contains:
- Row counts
- Block counts
- Sampling information
- Last analyzed time
- Stale statistics status
Checking Gathered Statistics
The following query was executed:
SQL> select
TABLE_NAME,
AVG_ROW_LEN,
SAMPLE_SIZE,
LAST_ANALYZED,
STALE_STATS,
NUM_ROWS,
BLOCKS,
EMPTY_BLOCKS
from dba_tab_statistics
where table_name='TAB1';
Output
TABLE_NAME AVG_ROW_LEN SAMPLE_SIZE LAST_ANALYZED STALE_STATS NUM_ROWS BLOCKS EMPTY_BLOCKS _____________ ______________ ______________ ________________ ______________ ___________ _________ _______________ TAB1 158 93743 24-05-26 NO 93743 108 0
Analyzing the Statistics Output
1. AVG_ROW_LEN
158
This means:
- Average row length is 158 bytes
Oracle uses this to estimate:
- I/O costs
- Memory usage
- Join costs
- Hash area requirements
2. SAMPLE_SIZE
93743
Oracle sampled:
- 93,743 rows
which equals the entire table.
This indicates:
Oracle performed a full statistics collection rather than partial sampling.
3. LAST_ANALYZED
24-05-26
This shows when statistics were last gathered.
The optimizer uses this timestamp to determine statistics freshness.
4. STALE_STATS
NO
This means:
- Statistics are current
- Oracle considers them fresh
If significant table modifications occur later:
- INSERTS
- UPDATES
- DELETES
Oracle may eventually mark statistics as:
YES
5. NUM_ROWS
93743
Oracle estimates the table contains:
- 93,743 rows
This matches the COUNT(*) query exactly.
6. BLOCKS
108
The table occupies:
- 108 Oracle blocks
Oracle uses this for:
- Cost calculations
- Full scan estimates
- I/O predictions
7. EMPTY_BLOCKS
0
This indicates:
- No completely empty blocks exist
which is usually a healthy sign for storage utilization.
Why Statistics Matter So Much
Without statistics, Oracle’s optimizer may generate poor execution plans.
Examples:
- Choosing full table scans unnecessarily
- Ignoring indexes
- Using incorrect join methods
- Underestimating cardinality
Good statistics are critical for:
- Performance tuning
- SQL optimization
- Parallel query execution
- Data warehouse workloads
Statistics in Autonomous Database
Oracle Autonomous Database automatically gathers optimizer statistics in most situations.
However, manual gathering is still useful when:
- Large data loads occur
- Bulk inserts happen
- Partition maintenance is performed
- Testing optimizer behavior
- Benchmarking workloads
Why GRANULARITY is Important for Partitioned Tables
Partitioned tables can have:
- Millions or billions of rows
- Different data distributions per partition
Global statistics alone may not be sufficient.
Using:
granularity=>'ALL'
allows Oracle to maintain:
- Detailed partition-level statistics
- Accurate pruning estimates
- Better optimizer decisions
Best Practices
- Gather statistics after large data loads
- Use parallel DEGREE carefully
- Use GRANULARITY='ALL' for partitioned tables
- Monitor STALE_STATS regularly
- Avoid unnecessary repeated statistics gathering
Key Takeaways
- DBMS_STATS.GATHER_TABLE_STATS collects optimizer statistics
- GRANULARITY controls which levels of statistics are gathered
- ALL gathers global, partition, and subpartition statistics
- DEGREE enables parallel statistics gathering
- DBA_TAB_STATISTICS stores optimizer metadata
- Fresh statistics improve query performance significantly
Conclusion
Optimizer statistics are the foundation of Oracle SQL performance tuning.
Understanding parameters like:
degree=>4 granularity=>'ALL'
helps DBAs and developers control how Oracle analyzes tables and generates execution plans.
Even in Autonomous Database, understanding statistics remains extremely important for:
- Performance optimization
- Partition tuning
- Large-scale analytics
- SQL troubleshooting
The output shown above demonstrates how Oracle successfully gathered accurate statistics for:
- 93,743 rows
- 108 blocks
- Fresh optimizer metadata
allowing the Cost-Based Optimizer to make smarter execution decisions.
No comments:
Post a Comment