I recently worked on a migration of Oracle Database to a new platform. The customer was sensitive to downtime. We looked at each item in the migration run book and asked: “Can we make it faster?”
We discussed exporting database statistics, and the question: Does dbms_stats.export_database_stats
include dictionary statistics?
The documentation states:
This procedure exports statistics for all objects in the database and stores them in the user statistics tables identified by statown.stattab.
What exactly do all objects mean?
Let’s Find Out
Here is a little test case.
I gather dictionary statistics. All but 77 dictionary tables now have statistics (it’s intentional that some are left un-analyzed):
exec dbms_stats.gather_dictionary_stats;
select count(*) cnt
from dba_tables
where owner in ('SYS', 'SYSTEM')
and last_analyzed is null;
CNT
----------
77
I export database statistics into a staging table:
grant dba to statuser identified by statuser;
begin
dbms_stats.create_stat_table(
'STATUSER',
'DBSTATS');
dbms_stats.export_database_stats(
stattab=>'DBSTATS',
statown=>'STATUSER');
dbms_stats.gather_table_stats(
'STATUSER',
'DBSTATS');
end;
/
I delete dictionary statistics. Now, 1674 dictionary tables are without statistics:
exec dbms_stats.delete_dictionary_stats(force=>true);
select count(*) cnt
from dba_tables
where owner in ('SYS', 'SYSTEM')
and last_analyzed is null;
CNT
----------
1674
I import statistics from the staging table. I am back at 77 dictionary tables without statistics.
begin
dbms_stats.import_database_stats(
stattab=>'DBSTATS',
statown=>'STATUSER',
force=>TRUE);
end;
/
select count(*) cnt
from dba_tables
where owner in ('SYS', 'SYSTEM')
and last_analyzed is null;
CNT
----------
77
Conclusion: dbms_stats.export_database_stats
includes dictionary statistics.
What about Fixed Objects Statistics
I can use the same test case as above (more or less). Here is the query I use to check for missing statistics on fixed objects:
select count(*) cnt
from dba_tab_statistics
where object_type='FIXED TABLE'
and last_analyzed is null;
The answer is: dbms_stats.export_database_stats
does not include fixed objects statistics.
To transfer fixed object statistics, you must use the dedicated export and import functions.
Is It a Good Idea to Transfer Dictionary Statistics?
Well… It depends.
If time allows, I recommend you always gather dictionary statistics in the target database at the appropriate time.
If you want to transfer statistics, this is my recommendation:
Type | Command | Recommendation |
---|---|---|
Full export | full=y |
Should be acceptable |
Full transportable | full=y transportable=always |
Should be acceptable |
Transportable tablespace | transport_tablespaces |
Hmm, not sure it’s a good idea |
Tablespace export | tablespaces=... |
Hmm, not sure it’s a good idea |
Schema export | schemas=... |
Hmm, probably a bad idea |
Table export | tables=... |
No, most likely a bad idea |