Hi Team ,
as per the requirement from application team , we need to copy table stats from one table to other table .
Both source and destination table are partition tables .
here we tested out in local system below steps :
1. created dummy table
create table t1(c1, c2)
partition by range (c1) (
partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (3000)
)
as
select level-1, level
from dual
connect by level <= 3000
;
2. gather stats
exec dbms_stats.gather_table_stats(sys, 't1', granularity=>'all');
3.exported stats in table "STATISTICS"
exec dbms_stats.create_stat_table('SYS','STATISTICS');
exec dbms_stats.export_table_stats('SYS','T1',NULL,'STATISTICS');
4. crete target table
create table t3(c1, c2)
partition by range (c1) (
partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (3000)
)
as
select level-1, level
from dual
connect by level <= 3000 ;
5.updated table name of exported stats
update statistics set c1='T2';
12 rows updated.
SQL> commit;
Commit complete.
6. Imported table in target partition table
exec dbms_stats.import_table_stats('SYS','T3', null, 'STATISTICS');
SQL> select partition_name,last_analyzed from dba_tab_partitions where table_name='T3' and
table_owner='SYS';
PARTITION_NAME LAST_ANAL
------------------------------ ---------
P1 09-NOV-18
P2 09-NOV-18
P3 09-NOV-18
SQL> select table_name, num_rows from dba_tables where table_name in ('T1','T3');
TABLE_NAME NUM_ROWS
------------------------------ ----------
T1 3000
T3 3000
Please confirm is this step is correct? As per my understanding their should be global stats and partition stats both we need to import, but here i am just taking export of table stats as whole and importing it.
Does this make sense or some other steps needs to be carried out here?
additionally in syntax exec dbms_stats.import_table_stats('SYS','T3', null, 'STATISTICS'); what does 'null' indicate ?
regards,
Krishna
Eeeeeek! Creating tables in SYS! No no no no no no no no no no no NO!
Always create your own user and make new tables there.
Anyway, the third parameter of export/import table stats is the partition name. Use this to manage stats for that partition only:
create table t1(c1, c2)
partition by range (c1) (
partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (3000)
)
as
select level-1, level
from dual
connect by level <= 3000;
create table t3(c1, c2)
partition by range (c1) (
partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (3000)
)
as
select level-1, level
from dual
connect by level <= 3000;
exec dbms_stats.gather_table_stats(user, 't1', granularity=>'all');
exec dbms_stats.create_stat_table(user,'STATISTICS');
exec dbms_stats.export_table_stats(user,'T1',NULL,'STATISTICS');
update statistics set c1='T3';
commit;
exec dbms_stats.import_table_stats(user,'T3', 'P1', 'STATISTICS');
select table_name, partition_name, num_rows, last_analyzed
from user_tab_statistics
where table_name like 'T_'
order by 1, 2;
TABLE_NAME PARTITION_NAME NUM_ROWS LAST_ANALYZED
T1 P1 1000 12-NOV-2018 02:44:28
T1 P2 1000 12-NOV-2018 02:44:28
T1 P3 1000 12-NOV-2018 02:44:28
T1 <null> 3000 12-NOV-2018 02:44:28
T3 P1 1000 12-NOV-2018 02:44:28
T3 P2 <null> <null>
T3 P3 <null> <null>
T3 <null> <null> <null>
exec dbms_stats.import_table_stats(user,'T3', null, 'STATISTICS');
select table_name, partition_name, num_rows, last_analyzed
from user_tab_statistics
where table_name like 'T_'
order by 1, 2;
TABLE_NAME PARTITION_NAME NUM_ROWS LAST_ANALYZED
T1 P1 1000 12-NOV-2018 02:44:28
T1 P2 1000 12-NOV-2018 02:44:28
T1 P3 1000 12-NOV-2018 02:44:28
T1 <null> 3000 12-NOV-2018 02:44:28
T3 P1 1000 12-NOV-2018 02:44:28
T3 P2 1000 12-NOV-2018 02:44:28
T3 P3 1000 12-NOV-2018 02:44:28
T3 <null> 3000 12-NOV-2018 02:44:28
As to whether you should import all the source table stats or just for one partition: it depends.
Why are you doing this vs. using normal stats gathering on the target table?
Do all the partitions store the same values?
If so a wholesale copy is probably right. But if you want to refresh only one partition, the answer's probably no. It comes down to what your goal is here.