Team,
Was reading through this documentation.
http://docs.oracle.com/database/122/SQLRF/CREATE-INDEX.htm#GUID-1F89BBC0-825F-4215-AF71-7588E31D8BFE__BABCHJDH <quote>
When an index, or some partitions or subpartitions of an index, are created UNUSABLE, no segment is allocated for the unusable object. The unusable index or index partition consumes no space in the database.
</quote>
How ever the quote holds good only for a LOCALLY partitioned index and not for a Globally partitioned index and non-partitioned index.
demo@ORA12C> create table t
2 partition by range( created_dt )
3 ( partition p2013 values less than
4 ( to_date('01-jan-2014','dd-mon-yyyy') ) ,
5 partition p2014 values less than
6 ( to_date('01-jan-2015','dd-mon-yyyy') ) ,
7 partition pmax values less than (maxvalue) )
8 as
9 select a.* ,
10 to_date('01-Jan-2013','dd-mon-yyyy') +
11 mod(rownum,1825) created_dt
12 from all_objects a ;
Table created.
demo@ORA12C> create index t_nonpart_idx on t(object_id);
Index created.
demo@ORA12C> create index t_globalpart_idx on t(object_id,owner)
2 global partition by hash(object_id) (
3 partition p1,
4 partition p2 ) ;
Index created.
demo@ORA12C> create index t_local_idx on t(object_name) local;
Index created.
demo@ORA12C> column index_name format a20
demo@ORA12C> column partition_name format a10
demo@ORA12C> column segment_name format a20
demo@ORA12C>
demo@ORA12C> select index_name,status
2 from user_indexes
3 where index_name = 'T_NONPART_IDX';
INDEX_NAME STATUS
-------------------- --------
T_NONPART_IDX VALID
demo@ORA12C>
demo@ORA12C> select index_name,partition_name,status
2 from user_ind_partitions
3 where index_name in ('T_GLOBALPART_IDX',
4 'T_LOCAL_IDX');
INDEX_NAME PARTITION_ STATUS
-------------------- ---------- --------
T_GLOBALPART_IDX P1 USABLE
T_GLOBALPART_IDX P2 USABLE
T_LOCAL_IDX P2013 USABLE
T_LOCAL_IDX P2014 USABLE
T_LOCAL_IDX PMAX USABLE
demo@ORA12C>
demo@ORA12C> select segment_name,partition_name,extents
2 from user_segments
3 where segment_name in ( 'T_NONPART_IDX' ,
4 'T_GLOBALPART_IDX' , 'T_LOCAL_IDX' )
5 order by segment_name,partition_name nulls first;
SEGMENT_NAME PARTITION_ EXTENTS
-------------------- ---------- ----------
T_GLOBALPART_IDX P1 23
T_GLOBALPART_IDX P2 23
T_LOCAL_IDX P2013 20
T_LOCAL_IDX P2014 20
T_LOCAL_IDX PMAX 23
T_NONPART_IDX 17
6 rows selected.
demo@ORA12C> alter table t
2 split partition pmax at
3 ( to_date('01-jan-2016','dd-mon-yyyy') )
4 into ( partition p2016, partition pmax);
Table altered.
demo@ORA12C> select index_name,status
2 from user_indexes
3 where index_name = 'T_NONPART_IDX';
INDEX_NAME STATUS
-------------------- --------
T_NONPART_IDX UNUSABLE
demo@ORA12C>
demo@ORA12C> select index_name,partition_name,status
2 from user_ind_partitions
3 where index_name in ('T_GLOBALPART_IDX',
4 'T_LOCAL_IDX');
INDEX_NAME PARTITION_ STATUS
-------------------- ---------- --------
T_GLOBALPART_IDX P1 UNUSABLE
T_GLOBALPART_IDX P2 UNUSABLE
T_LOCAL_IDX P2013 USABLE
T_LOCAL_IDX P2014 USABLE
T_LOCAL_IDX P2016 UNUSABLE
T_LOCAL_IDX PMAX UNUSABLE
6 rows selected.
demo@ORA12C> select segment_name,partition_name,extents
2 from user_segments
3 where segment_name in ( 'T_NONPART_IDX' ,
4 'T_GLOBALPART_IDX' , 'T_LOCAL_IDX' )
5 order by segment_name,partition_name nulls first;
SEGMENT_NAME PARTITION_ EXTENTS
-------------------- ---------- ----------
T_GLOBALPART_IDX P1 23
T_GLOBALPART_IDX P2 23
T_LOCAL_IDX P2013 20
T_LOCAL_IDX P2014 20
T_NONPART_IDX 17
demo@ORA12C>
Could you help me to understand why these UNUSED segments are not getting released in case of a Globally partitioned index and non-partitioned index ?
The key point here is it's when you
create the indexes they need to be UNUSABLE.
The script creates USABLE indexes. Splitting the partition doesn't re-create the global indexes. So they keep their extents. Many of these will relate to rows unaffected by the split.
If you add the unusable when creating the index, you'll see the database creates no extents:
create table t
partition by range( created_dt )
( partition p2013 values less than
( to_date('01-jan-2014','dd-mon-yyyy') ) ,
partition p2014 values less than
( to_date('01-jan-2015','dd-mon-yyyy') ) ,
partition pmax values less than (maxvalue) )
as
select a.* ,
to_date('01-Jan-2013','dd-mon-yyyy') +
mod(rownum,1825) created_dt
from all_objects a ;
create index t_nonpart_idx on t(object_id) unusable;
create index t_globalpart_idx on t(object_id,owner)
global partition by hash(object_id) (
partition p1,
partition p2 ) unusable;
create index t_local_idx on t(object_name) local unusable;
select segment_name,partition_name,extents
from user_segments
where segment_name in ( 'T_NONPART_IDX' , 'T_GLOBALPART_IDX' , 'T_LOCAL_IDX' )
order by segment_name,partition_name nulls first;
no rows selected
alter table t
split partition pmax at
( to_date('01-jan-2016','dd-mon-yyyy') )
into ( partition p2016, partition pmax);
select segment_name,partition_name,extents
from user_segments
where segment_name in ( 'T_NONPART_IDX' , 'T_GLOBALPART_IDX' , 'T_LOCAL_IDX' )
order by segment_name,partition_name nulls first;
no rows selected
The indexes are UNUS
ABLE, not UNUS
ED.
PS - the LiveSQL link is supposed to point to
your script. Not its homepage!