1. These commands solve different problems - you can't compare them directly.
ALTER TABLE ... SHRINK reclaims "wasted" space in the table. For more on this see:
https://asktom.oracle.com/pls/apex/asktom.search?tag=what-is-the-difference-between-shrink-move-and-impdp TRUNCATE removes all the data from the table! As a side effect, it also deallocates space from the table (by default).
So if you're clearing down a table TRUNCATE is
often the way to go. Remember it commits, making it impractical for some use cases. If you need to keep the data, then you'll have to use shrink or move.
2. The indexes are maintained as part of these operations. Shrinking a table won't change the size of any indexes; truncating deallocates index storage as well as the table's:
create table t ( c1 constraint pk primary key, c2 )
enable row movement
as
select level c1, level || rpad ( 'stuff', 100, 'f' ) c2
from dual
connect by level <= 10000;
create index i2 on t ( c2 );
delete t
where c1 <= 9000;
commit;
select segment_name, bytes from user_segments
where segment_name in ( 'T', 'PK', 'I2' );
SEGMENT_NA BYTES
---------- ----------
I2 2097152
PK 262144
T 2097152
alter table t shrink space;
select segment_name, bytes from user_segments
where segment_name in ( 'T', 'PK', 'I2' );
SEGMENT_NA BYTES
---------- ----------
I2 2097152
PK 262144
T 196608
alter index pk
rebuild;
select segment_name, bytes from user_segments
where segment_name in ( 'T', 'PK', 'I2' );
SEGMENT_NA BYTES
---------- ----------
I2 2097152
PK 65536
T 196608
truncate table t;
select segment_name, bytes from user_segments
where segment_name in ( 'T', 'PK', 'I2' );
SEGMENT_NA BYTES
---------- ----------
I2 65536
PK 65536
T 65536
3. For what purpose? Note that from 12.1 you can gather session-specific stats for GTTs; this may be the best option:
https://oracle-base.com/articles/12c/session-private-statistics-for-global-temporary-tables-12cr1 4. Are these GTTs or normal tables?