Tom,
I did a test using UPDATE GLOBAL INDEXES clause and without it and not only did it take a long time ( 85 seconds versus 6 seconds), the indexes took more space (two and a half times more) and redo generated was tremendous.
Here is the test. My question is why would anyone want to use UPDATE GLOBAL INDEXES option, HA or no HA, when the consequences are so bad?
$ sqlplus testuser/testpassword @test.sql
SQL*Plus: Release 11.1.0.7.0 - Production on Tue Oct 6 12:27:28 2009
Copyright (c) 1982, 2008, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.1.0.7.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
SQL> DROP TABLE t PURGE;
Table dropped.
Elapsed: 00:00:00.17
SQL>
SQL> CREATE TABLE t TABLESPACE large_data01 PARTITION BY RANGE (created) (PARTITION p_maxvalue VALUES LESS THAN (maxvalue))
2 AS SELECT * FROM all_objects
3 UNION ALL SELECT * FROM all_objects
4 UNION ALL SELECT * FROM all_objects
5 UNION ALL SELECT * FROM all_objects
6 UNION ALL SELECT * FROM all_objects
7 UNION ALL SELECT * FROM all_objects
8 UNION ALL SELECT * FROM all_objects
9 UNION ALL SELECT * FROM all_objects
10 UNION ALL SELECT * FROM all_objects;
Table created.
Elapsed: 00:00:28.49
SQL>
SQL> CREATE INDEX i1 ON t (owner, object_name) TABLESPACE large_data01;
Index created.
Elapsed: 00:00:03.15
SQL> CREATE INDEX i2 ON t (object_id) TABLESPACE large_data01;
Index created.
Elapsed: 00:00:00.83
SQL> CREATE INDEX i3 ON t (object_type, created) TABLESPACE large_data01;
Index created.
Elapsed: 00:00:01.66
SQL>
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'TREXONE_DATA',TABNAME=>'T',METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',DEGREE=>2, CASCADE=>TRUE,GRANULARITY=>'ALL');
PL/SQL procedure successfully completed.
Elapsed: 00:00:05.04
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name = 'T';
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
T 61865984 7552 59
Elapsed: 00:00:00.73
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name IN ('I1','I2','I3');
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
I1 26214400 3200 25
I2 11534336 1408 11
I3 18874368 2304 18
Elapsed: 00:00:01.03
SQL>
SQL> ALTER TABLE t SPLIT PARTITION p_maxvalue AT (TO_DATE('01-MAR-2009','DD-MON-YYYY')) INTO (PARTITION p_200902 NOLOGGING, PARTITION p_maxvalue NOLOGGING);
Table altered.
Elapsed: 00:00:01.51
SQL>
SQL> ALTER INDEX I1 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:03.16
SQL> ALTER INDEX I2 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:00.75
SQL> ALTER INDEX I3 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:01.18
SQL>
SQL> exec runstats_pkg.rs_middle;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.11
SQL> exec runstats_pkg.rs_stop (1000);
Run1 ran in 661 hsecs
Run2 ran in 0 hsecs
run 1 ran in 66100% of the time
Name Run1 Run2 Diff
<< deleted to keep it short >>
STAT...redo size 574,072 4,224 -569,848
<< deleted to keep it short >>
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
162,655 796 -161,859 20,434.05%
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.35
SQL>
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'TREXONE_DATA',TABNAME=>'T',METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',DEGREE=>2, CASCADE=>TRUE,GRANULARITY=>'ALL');
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.45
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name = 'T';
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
T 54525952 6656 52
T 7340032 896 7
Elapsed: 00:00:01.02
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name IN ('I1','I2','I3');
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
I1 26214400 3200 25
I2 11534336 1408 11
I3 18874368 2304 18
Elapsed: 00:00:01.03
SQL> --------------------------------------
SQL> --reset
SQL> ALTER TABLE t MERGE PARTITIONS p_200902, p_maxvalue INTO PARTITION p_maxvalue nologging;
Table altered.
Elapsed: 00:00:01.50
SQL> ALTER INDEX I1 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:03.20
SQL> ALTER INDEX I2 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:00.66
SQL> ALTER INDEX I3 REBUILD NOLOGGING;
Index altered.
Elapsed: 00:00:01.20
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name = 'T';
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
T 61865984 7552 59
Elapsed: 00:00:00.69
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name IN ('I1','I2','I3');
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
I1 26214400 3200 25
I2 11534336 1408 11
I3 18874368 2304 18
Elapsed: 00:00:01.05
SQL> --------------------------------------
SQL> -- Test with UPDATE GLOBAL INDEXES
SQL> exec runstats_pkg.rs_start;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.22
SQL>
SQL> ALTER TABLE t SPLIT PARTITION p_maxvalue AT (TO_DATE('01-MAR-2009','DD-MON-YYYY'))
2 INTO (PARTITION p_200902 NOLOGGING, PARTITION p_maxvalue NOLOGGING) UPDATE GLOBAL INDEXES;
Table altered.
Elapsed: 00:01:25.18
SQL>
SQL> exec runstats_pkg.rs_middle;
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.11
SQL> exec runstats_pkg.rs_stop (1000);
Run1 ran in 8518 hsecs
Run2 ran in 1 hsecs
run 1 ran in 851800% of the time
Name Run1 Run2 Diff
<< deleted to keep it short >>
STAT...redo size 320,566,140 4,584-320,561,556
<< deleted to keep it short >>
Run1 latches total versus runs -- difference and pct
Run1 Run2 Diff Pct
90,900,946 371 -90,900,575##########%
PL/SQL procedure successfully completed.
Elapsed: 00:00:00.35
SQL>
SQL> EXEC DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'TREXONE_DATA',TABNAME=>'T',METHOD_OPT=>'FOR ALL COLUMNS SIZE 1',DEGREE=>2, CASCADE=>TRUE,GRANULARITY=>'ALL');
PL/SQL procedure successfully completed.
Elapsed: 00:00:04.56
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name = 'T';
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
T 54525952 6656 52
T 7340032 896 7
Elapsed: 00:00:01.02
SQL> SELECT segment_name, bytes, blocks, extents FROM user_segments WHERE segment_name IN ('I1','I2','I3');
SEGMENT_NAME BYTES BLOCKS EXTENTS
------------------------------ ---------- ---------- ----------
I1 59768832 7296 57
I2 25165824 3072 24
I3 51380224 6272 49
Elapsed: 00:00:01.03