(1.) 表空间及分区表的概念
表空间:
是一个或多个数据文件的集合,所有的数据对象都存放在指定的表空间中,但主要存放的是表, 所以称作表空间。
分区表:
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上表仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
( 2).表分区的具体作用
Oracle的表分区功能通过改善可管理性、性能和可用性,从而为各式应用程序带来了极大的好处。通常,分区可以使某些查询以及维护操作的性能大大提高。此外,分区还可以极大简化常见的管理任务,分区是构建千兆字节数据系统或超高可用性系统的关键工具。
分区功能能够将表、索引或索引组织表进一步细分为段,这些数据库对象的段叫做分区。每个分区有自己的名称,还可以选择自己的存储特性。从数据库管理员的角度来看,一个分区后的对象具有多个段,这些段既可进行集体管理,也可单独管理,这就使数据库管理员在管理分区后的对象时有相当大的灵活性。但是,从应用程序的角度来看,分区后的表与非分区表完全相同,使用 SQL DML 命令访问分区后的表时,无需任何修改。
什么时候使用分区表:
1、表的大小超过2GB。
2、表中包含历史数据,新的数据被增加都新的分区中。
(3).表分区的优缺点
表分区有以下优点:
1、改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索速度。
2、增强可用性:如果表的某个分区出现故障,表在其他分区的数据仍然可用;
3、维护方便:如果表的某个分区出现故障,需要修复数据,只修复该分区即可;
4、均衡I/O:可以把不同的分区映射到磁盘以平衡I/O,改善整个系统性能。
Range分区:
range分区是应用范围比较广的表分区方式,它是以列的值的范围来做为分区的划分条件,将记录放到列值
所对应的分区中。
比如按时间划分,2012年1月的数据放到a分区,2月的数据放到b分区,在创建的时候,需要指定基于的列,以及分区的范围值。
实验一:
create table dba (id number, time date) partition by range (time)
(
partition p1 values less than (to_date('2012-10-1', 'yyyy-mm-dd')),
partition p2 values less than (to_date('2012-11-1', 'yyyy-mm-dd')),
partition p3 values less than (to_date('2012-12-1', 'yyyy-mm-dd')),
partition p4 values less than (maxvalue)
)
注:不必为最后一个分区指定最大值,maxvalue关键字会告诉oracle使用这个分区来存储在前面几个分区中不能存储的数据。
Hash分区:
散列分区(hash分区)通过在分区键值上执行一个散列函数来决定数据的物理位置。在范围分区中,分区键的连续值通常存储在相同的分区中,
而在散列分区中,连续的分区键值一般不存储在相同的分区中。散列分区把记录分布在比范围分区更多的分区上,
这降低了I/O争用的可能性。
实验二:
create table test
(
transaction_id number primary key,
item_id number(8) not null
)
partition by hash(transaction_id)
(
partition part_01 tablespace tablespace01,
partition part_02 tablespace tablespace02,
partition part_03 tablespace tablespace03
);
这里,我们指定了每个分区所对应的表空间。
List 分区:
List 分区也需要指定列的值,其分区值必须明确指定,该分区列只能有一个,
不能像 range 或者 hash 分区那样同时指定多个列做为分区依赖列,但它的单个分
区对应值可以是多个。
在分区时必须确定分区列可能存在的值,一旦插入的列值不在分区范围内,
则插入/更新就会失败, 因此通常建议使用 list 分区时,要创建一个 default 分区
存储那些不在指定范围内的记录,类似 range 分区中的 maxvalue 分区。
实验三:
create table custaddr
(
id varchar2(15 byte) not null,
areacode varchar2(4 byte)
)
partition by list (areacode)
( partition t_list025 values ('025'),
partition t_list372 values ('372') ,
partition t_list510 values ('510'),
partition p_other values (default)
);
注:
组合分区:
如果某表按照某列分区之后,仍然较大,或者是一些其它的需求,还可以通
过分区内再建子分区的方式将分区再分区,即组合分区的方式。
组合分区在10g中有两种:range-hash,range-list。注意顺序,根分区只
能是 range 分区,子分区可以是 hash 分区或 list 分区。在11g中这部分功能有所增强,这里我就不介绍了。
实验四:
create table test
(
transaction_id number primary key,
transaction_date date
)
partition by range(transaction_date) subpartition by hash(transaction_id)
subpartitions 3 store in (tablespace01,tablespace02,tablespace03)
(
partition part_01 values less than(to_date(‘2009-01-01‘,‘yyyy-mm-dd‘)),
partition part_02 values less than(to_date(‘2010-01-01‘,‘yyyy-mm-dd‘)),
partition part_03 values less than(maxvalue)
);
create table emp_sub_template (deptno number, empname varchar(32), grade
number)
partition by range(deptno) subpartition by hash(empname)
subpartition template
(subpartition a tablespace ts1,
subpartition b tablespace ts2,
subpartition c tablespace ts3,
subpartition d tablespace ts4
)
(partition p1 values less than (1000),
partition p2 values less than (2000),
partition p3 values less than (maxvalue)
);
create table quarterly_regional_sales
(deptno number, item_no varchar2(20),
txn_date date, txn_amount number, state varchar2(2))
tablespace ts4
partition by range (txn_date)
subpartition by list (state)
(partition q1_1999 values less than (to_date('1-apr-1999','dd-mon-yyyy'))
(subpartition q1_1999_northwest values ('or', 'wa'),
subpartition q1_1999_southwest values ('az', 'ut', 'nm'),
subpartition q1_1999_northeast values ('ny', 'vm', 'nj'),
subpartition q1_1999_southeast values ('fl', 'ga'),
subpartition q1_1999_northcentral values ('sd', 'wi'),
subpartition q1_1999_southcentral values ('ok', 'tx')
),
partition q2_1999 values less than ( to_date('1-jul-1999','dd-mon-yyyy'))
(subpartition q2_1999_northwest values ('or', 'wa'),
subpartition q2_1999_southwest values ('az', 'ut', 'nm'),
subpartition q2_1999_northeast values ('ny', 'vm', 'nj'),
subpartition q2_1999_southeast values ('fl', 'ga'),
subpartition q2_1999_northcentral values ('sd', 'wi'),
subpartition q2_1999_southcentral values ('ok', 'tx')
),
partition q3_1999 values less than (to_date('1-oct-1999','dd-mon-yyyy'))
(subpartition q3_1999_northwest values ('or', 'wa'),
subpartition q3_1999_southwest values ('az', 'ut', 'nm'),
subpartition q3_1999_northeast values ('ny', 'vm', 'nj'),
subpartition q3_1999_southeast values ('fl', 'ga'),
subpartition q3_1999_northcentral values ('sd', 'wi'),
subpartition q3_1999_southcentral values ('ok', 'tx')
),
partition q4_1999 values less than ( to_date('1-jan-2000','dd-mon-yyyy'))
(subpartition q4_1999_northwest values ('or', 'wa'),
subpartition q4_1999_southwest values ('az', 'ut', 'nm'),
subpartition q4_1999_northeast values ('ny', 'vm', 'nj'),
subpartition q4_1999_southeast values ('fl', 'ga'),
subpartition q4_1999_northcentral values ('sd', 'wi'),
subpartition q4_1999_southcentral values ('ok', 'tx')
)
)
间隔分区:
在oracle11g中可用的另一种新的分区类型是间隔分区。在间隔分区中,不必为每个分区
指定特定的范围值,而是指定间隔持续的时间。也就是说,不是指定分区1在
1月31日结束,分区2在2月29日结束,而是指定每个分区为1个月长的时间。
当插入新行时,oracle将根据间隔定义确定将此行插入到哪个分区。如果没有为那个月创建分区,
数据库将自动创建一个分区。
create table invoice_headers
(
invoice_num number,
customer_num number,
invoice_date date
)
partition by range (invoice_date)
interval (numtoyminterval (1,'month'))
(
partition p1101 values
less than (to_date('2011-02-01','yyyy-mm-dd'))
);
需要注意的是,如果依靠间隔分区自动创建分区,应用程序开发人员将得不到一致的分区
名称,因为oracle为它自动创建的每个分区创建系统生成的名称。
接下来我来通过实验方法将普通表转换成分区表。
1. Insert with a subquery method
2. Partition exchange method
3. Export/import method
1.插入: Insert with a subquery method
这种方法就是使用 insert 来实现。 当然在创建分区表的时候可以一起插入数据,也可以创建好后在insert 进去。
这种方法采用DDL语句,不产生UNDO,
只产生少量 REDO,建表完成后数据已经在分布到各个分区中。
实验一:
create table interval_wjh
partition by range (hire_date)
interval ( numtoyminterval (1, 'month') )
(partition part1
values less than (to_date ('02/14/2012', 'mm/dd/yyyy')))
as
select id, time_fee from test_table;
2.交换分区 Partition exchange method
这种方法只是对数据字典中分区和表的定义进行了修改,没有数据的修改或
复制,效率最高。适用于包含大数据量的表转到分区表中的一个分区的操作。尽
量在闲时进行操作。
交换分区的操作步骤如下:
1. 创建分区表,假设有 2 个分区,P1,P2.
2. 创建表 A 存放 P1 规则的数据。
3. 创建表 B 存放 P2 规则的数据。
4. 用表 A 和 P1 分区交换, 把表 A 的数据放到到 P1 分区
5. 用表 B 和 p2 分区交换, 把表 B 的数据存放到 P2 分区
实验二:
创建分区表:
sql> create table P_p
2 (id number,time date)
3 partition by range(time)
4 (
5 partition p1 values less than (to_date('2012-08-12', 'yyyy-mm-dd')),
6 partition p2 values less than (to_date('2013-11-22', 'yyyy-mm-dd'))
7 );
表已创建。
创建 2 个分别对应分区的基表:
SQL> CREATE TABLE P_p1 as SELECT employee_id,hire_date FROM test_table WHERE
hire_date
CREATE TABLE P_p2 as SELECT employee_id,hire_date FROM test_table WHERE
time_fee
表已创建。
将2个基表与2个分区进行交换:
SQL> alter table P_p exchange partition p1 with table dba_p1;
表已更改。
SQL> alter table P_p exchange partition p2 with table dba_p2;
表已更改
分区表的其他操作
添加新的分区
添加新的分区有 2 中情况:
(1) 原分区里边界是 maxvalue 或者 default。 这种情况下,我们需要把边界分
区 drop 掉,加上新分区后,在添加上新的分区。 或者采用 split,对边界分区进
行拆分。
(2) 没有边界分区的。 这种情况下,直接添加分区就可以了。
以边界分区添加新分区示例:
(1) 分区表和索引的信息如下:
SQL> create table David
2 (
3 id varchar2(15 byte) not null,
4 areacode varchar2(4 byte)
5 )
6 partition by list (areacode)
7 (
8 partition t_list536 values ('536') tablespace TBS1,
9 partition p_other values (default)tablespace TBS2
10 );
表已创建。
SQL> create index David_id on David(id)
2 local (
3 partition t_list556 tablespace icd_service,
4 partition p_other tablespace icd_service
5 );
索引已创建。
(2) 插入几条测试数据:
SQL> insert into custaddr values('1','556');
已创建 1 行。
SQL> insert into custaddr values('2','551');
已创建 1 行。
SQL> insert into custaddr values('3','555');
已创建 1 行。
SQL> commit;
提交完成。
删除 default 分区
sql> alter table David drop partition p_other;
表已更改。
添加新分区
SQL> alter table David add partition t_list551 values('551') tablespace TBS1;
表已更改。
添加 default 分区
SQL> alter table David add partition p_other values (default) tablespace
TBS2;
表已更改。
select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
CUSTADDR T_LIST556
CUSTADDR T_LIST551
CUSTADDR P_OTHER
对于局部索引, oracle 会自动增加一个局部分区索引。验证一下:
sql> select owner,index_name,table_name,partitioning_type from dba_part_indexes
where index_name='ix_custaddr_id';
owner index_name table_name
icd ix_custaddr_id custaddr
sql> select index_owner,index_name,partition_name from dba_ind_partitions where
index_name='ix_custaddr_id';
index_owner index_name partition_name
------------------------------ ------------------------------ ------------------
icd ix_custaddr_id p_other
icd ix_custaddr_id t_list551
icd ix_custaddr_id t_list556
split 分区拆分
在上节中,我们说明了可以使用 split 的方式来添加分区。 这里我们用 split
方法继续上面的实验。
sql> alter table david split partition p_other values('552') into (partition t_list552
tablespace TBS1, partition p_other tablespace TBS2);
表已更改。
注意:这里红色的地方,如果是 Range 类型的,使用 at, List 使用 Values。
SQL> select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
CUSTADDR T_LIST556
CUSTADDR T_LIST551
CUSTADDR T_LIST552
CUSTADDR P_OTHER
SQL> select index_owner,index_name,partition_name from dba_ind_partitions
where index_name='DAVID_ID';
index_owner index_name partition_name
------------------------------ ------------------------------ ------------------
icd ix_custaddr_id p_other
icd ix_custaddr_id t_list551
icd ix_custaddr_id t_list552
icd ix_custaddr_id t_list556
注意:分区表会自动维护局部分区索引。全局索引会失效,需要进行 rebuild。
合并分区 Merge
相邻的分区可以 merge 为一个分区,新分区的下边界为原来边界值较低的分区,上边界为原来边界值较高的分区, 原先的局部索引相应也会合并,全局索引
会失效,需要 rebuild。
alter table custaddr merge partitions t_list552,p_other into partition p_other;
表已更改。
SQL> select index_owner,index_name,partition_name from dba_ind_partitions
where index_name='CUSTADDR_ID';
index_owner index_name partition_name
-------------------- ------------------------------ ------------------
icd custaddr_id p_other
icd custaddr_id t_list551
icd custaddr_id t_list556
SQL> select table_name,partition_name from user_tab_partitions where
table_name='CUSTADDR';
table_name partition_name
------------------------------ ------------------------------
david t_list556
david t_list551
david p_other
移动分区
SQL> alter table david move partition P_OTHER tablespace system;
表已更改。
SQL> alter table david move partition P_OTHER tablespace icd_service;
表已更改。
注意: 分区移动会自动维护局部分区索引, oracle 不会自动维护全局索引,所
以需要我们重新 rebuild 分区索引,具体需要 rebuild 哪些索引,可以通过
dba_part_indexes,dba_ind_partitions 去判断。
SQL> Select index_name,status From user_indexes Where
table_name='CUSTADDR';
INDEX_NAME STATUS
------------------------------ --------
IX_CUSTADDR_ID N/A
Truncate 分区
SQL> select * from david partition(T_LIST556);
ID AREA
--------------- ----
1 556
SQL> alter table david truncate partition(T_LIST556);
表被截断。
SQL> select * from david partition(T_LIST556);
未选定行
Truncate 相对 delete 操作很快,数据仓库中的大量数据的批量数据加载可能
会有用到; 截断分区同样会自动维护局部分区索引,同时会使全局索引 unusable,
需要重建
Drop 分区
alter table david drop partition T_LIST551;
表已更改。
SQL> select table_name,partition_name from user_tab_partitions where
table_name='DAVID';
TABLE_NAME PARTITION_NAME
------------------------------ ------------------------------
CUSTADDR T_LIST556
CUSTADDR P_OTHER
同样会自动维护局部分区索引,同时会使全局索引 unusable,需要重建
ORACLE12C 在线表分区
概念:
Nonpartitioned tables can be converted to partitioned tables online. Indexes are maintained as part of this operation and can be partitioned as well. The conversion has no impact on the ongoing DML operations.
可以将非分区表转换为在线分区表。索引作为该操作的一部分被维护,也可以被分区。转换对正在进行的DML操作没有影响。
The online conversion of a nonpartitioned table to a partitioned table enables any application to adopt partitioning without application downtime. Customers can adopt partitioning for any system and evolve tables as needed to benefit from the partitioning for large tables.
将非分区表的在线转换到分区表可以使任何应用程序在不使用应用程序停机的情况下采用分区。客户可以通过对任何系统进行分区,并根据需要对表进行演化,以从大型表的分区中获益。
限制:
有一些与此功能相关的限制。
它不能被用来分割一个索引有序的表(IOT)。
如果表有域索引,就不能使用它。
您只能在脱机模式下将表转换为reference-partitioned子表。
实例:
1 创建表并插入数据,创建索引
[oracle@host1 ~]$ sqlplus / as sysdba
SQL*Plus: Release 12.2.0.1.0 Production on Sat Aug 26 17:51:26 2017
Copyright (c) 1982, 2016, Oracle. All rights reserved.
Connected to:
Oracle Database 12c Enterprise Edition Release 12.2.0.1.0 - 64bit Production
SQL> DROP TABLE t1 PURGE;
DROP TABLE t1 PURGE
*
ERROR at line 1:
ORA-00942: table or view does not exist
SQL> CREATE TABLE t1 (
id NUMBER,
description VARCHAR2(50),
created_date DATE,
CONSTRAINT t1_pk PRIMARY KEY (id)
);
Table created.
SQL> CREATE INDEX t1_created_date_idx ON t1(created_date);SQL>
Index created.
SQL> INSERT INTO t1
SELECT level,
'Description for ' || level,
ADD_MONTHS(TO_DATE('01-JAN-2017', 'DD-MON-YYYY'), -TRUNC(DBMS_RANDOM.value(1,4)-1)*12)
FROM dual
CONNECT BY level <= 1000;
1000 rows created.
SQL> COMMIT;
Commit complete.
2 我们可以看到数据被分配在3个时间段内。
SQL> SELECT created_date, COUNT(*)
FROM t1
GROUP BY created_date
ORDER BY 1;
CREATED_DATE COUNT(*)
------------ ----------
01-JAN-15 322
01-JAN-16 355
01-JAN-17 323
3 分区表 我们可以使用ALTER TABLE ... MODIFY将表转换为分区表。下面是这个操作的一些基本示例。添加在线关键字允许在网上完成操作。
3.1 基本的离线操作。
SQL> ALTER TABLE t1 MODIFY
PARTITION BY RANGE (created_date) (
PARTITION t1_part_2015 VALUES LESS THAN (TO_DATE('01-JAN-2016','DD-MON-YYYY')),
PARTITION t1_part_2016 VALUES LESS THAN (TO_DATE('01-JAN-2017','DD-MON-YYYY')),
PARTITION t1_part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','DD-MON-YYYY'))
);
Table altered.
SQL> COLUMN table_name FORMAT A20
SQL> COLUMN partition_name FORMAT A20
SQL> SELECT table_name, partition_name
FROM user_tab_partitions where TABLE_NAME ='T1'
ORDER BY 1,2;
TABLE_NAME PARTITION_NAME
-------------------- --------------------
T1 T1_PART_2015
T1 T1_PART_2016
T1 T1_PART_2017
3.2在线分区表
SQL> ALTER TABLE t1 MODIFY
PARTITION BY RANGE (created_date) (
PARTITION t1_part_2015 VALUES LESS THAN (TO_DATE('01-JAN-2016','DD-MON-YYYY')),
PARTITION t1_part_2016 VALUES LESS THAN (TO_DATE('01-JAN-2017','DD-MON-YYYY')),
PARTITION t1_part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','DD-MON-YYYY'))
) ONLINE; 6
Table altered.
SQL> COLUMN table_name FORMAT A20
SQL> COLUMN partition_name FORMAT A20
SQL> SELECT table_name, partition_name
FROM user_tab_partitions where TABLE_NAME ='T1'
ORDER BY 1,2; 2 3
TABLE_NAME PARTITION_NAME
-------------------- --------------------
T1 T1_PART_2015
T1 T1_PART_2016
T1 T1_PART_2017
3.3在线操作,修改索引分区。
SQL> ALTER TABLE t1 MODIFY
PARTITION BY RANGE (created_date) (
PARTITION t1_part_2015 VALUES LESS THAN (TO_DATE('01-JAN-2016','DD-MON-YYYY')),
PARTITION t1_part_2016 VALUES LESS THAN (TO_DATE('01-JAN-2017','DD-MON-YYYY')),
PARTITION t1_part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','DD-MON-YYYY'))
) ONLINE
UPDATE INDEXES
(
t1_pk GLOBAL,
t1_created_date_idx LOCAL
);
Table altered.
--在运行最后一个示例之后,我们可以看到表和分区索引的新分区
SQL> COLUMN table_name FORMAT A20
SQL> COLUMN table_name FORMAT A20
SQL> SELECT table_name, partition_name
FROM user_tab_partitions where TABLE_NAME ='T1'
ORDER BY 1,2;
TABLE_NAME PARTITION_NAME
-------------------- --------------------
T1 T1_PART_2015
T1 T1_PART_2016
T1 T1_PART_2017
SQL> COLUMN index_name FORMAT A20
SQL> COLUMN partition_name FORMAT A20
SQL> SELECT index_name, partition_name, status
FROM user_ind_partitions where INDEX_NAME='T1_CREATED_DATE_IDX'
ORDER BY 1,2;
INDEX_NAME PARTITION_NAME STATUS
-------------------- -------------------- --------
T1_CREATED_DATE_IDX T1_PART_2015 USABLE
T1_CREATED_DATE_IDX T1_PART_2016 USABLE
T1_CREATED_DATE_IDX T1_PART_2017 USABLE
4 组合分区表
原始表也可以使用ALTER table进行复合分区…修改命令。在本例中,我们将原始表转换为range-hash分区表。
SQL> ALTER TABLE t1 MODIFY
PARTITION BY RANGE (created_date) SUBPARTITION BY HASH (id)(
PARTITION t1_part_2015 VALUES LESS THAN (TO_DATE('01-JAN-2016','DD-MON-YYYY')) (
SUBPARTITION t1_sub_part_2015_1,
SUBPARTITION t1_sub_part_2015_2,
SUBPARTITION t1_sub_part_2015_3,
SUBPARTITION t1_sub_part_2015_4
),
PARTITION t1_part_2016 VALUES LESS THAN (TO_DATE('01-JAN-2017','DD-MON-YYYY')) (
SUBPARTITION t1_sub_part_2016_1,
SUBPARTITION t1_sub_part_2016_2,
SUBPARTITION t1_sub_part_2016_3,
SUBPARTITION t1_sub_part_2016_4
),
PARTITION t1_part_2017 VALUES LESS THAN (TO_DATE('01-JAN-2018','DD-MON-YYYY')) (
SUBPARTITION t1_sub_part_2017_1,
SUBPARTITION t1_sub_part_2017_2,
SUBPARTITION t1_sub_part_2017_3,
SUBPARTITION t1_sub_part_2017_4
)
) ONLINE
UPDATE INDEXES
(
t1_pk GLOBAL,
t1_created_date_idx LOCAL
);
Table altered.
可以使用以下查询显示表和分区索引的子分区。
SQL> COLUMN table_name FORMAT A20
SQL> COLUMN partition_name FORMAT A20
SQL> COLUMN subpartition_name FORMAT A20
SQL> SELECT table_name, partition_name, subpartition_name
FROM user_tab_subpartitions where TABLE_NAME ='T1'
ORDER BY 1,2, 3;
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME
-------------------- -------------------- --------------------
T1 T1_PART_2015 T1_SUB_PART_2015_1
T1 T1_PART_2015 T1_SUB_PART_2015_2
T1 T1_PART_2015 T1_SUB_PART_2015_3
T1 T1_PART_2015 T1_SUB_PART_2015_4
T1 T1_PART_2016 T1_SUB_PART_2016_1
T1 T1_PART_2016 T1_SUB_PART_2016_2
T1 T1_PART_2016 T1_SUB_PART_2016_3
T1 T1_PART_2016 T1_SUB_PART_2016_4
T1 T1_PART_2017 T1_SUB_PART_2017_1
T1 T1_PART_2017 T1_SUB_PART_2017_2
T1 T1_PART_2017 T1_SUB_PART_2017_3
TABLE_NAME PARTITION_NAME SUBPARTITION_NAME
-------------------- -------------------- --------------------
T1 T1_PART_2017 T1_SUB_PART_2017_4
12 rows selected.
SQL> COLUMN index_name FORMAT A20
SQL> COLUMN partition_name FORMAT A20
SQL> COLUMN subpartition_name FORMAT A20
SQL> SELECT index_name, partition_name, subpartition_name, status
FROM user_ind_subpartitions where INDEX_NAME='T1_CREATED_DATE_IDX'
ORDER BY 1,2;
INDEX_NAME PARTITION_NAME SUBPARTITION_NAME STATUS
-------------------- -------------------- -------------------- --------
T1_CREATED_DATE_IDX T1_PART_2015 T1_SUB_PART_2015_1 USABLE
T1_CREATED_DATE_IDX T1_PART_2015 T1_SUB_PART_2015_2 USABLE
T1_CREATED_DATE_IDX T1_PART_2015 T1_SUB_PART_2015_3 USABLE
T1_CREATED_DATE_IDX T1_PART_2015 T1_SUB_PART_2015_4 USABLE
T1_CREATED_DATE_IDX T1_PART_2016 T1_SUB_PART_2016_1 USABLE
T1_CREATED_DATE_IDX T1_PART_2016 T1_SUB_PART_2016_2 USABLE
T1_CREATED_DATE_IDX T1_PART_2016 T1_SUB_PART_2016_4 USABLE
T1_CREATED_DATE_IDX T1_PART_2016 T1_SUB_PART_2016_3 USABLE
T1_CREATED_DATE_IDX T1_PART_2017 T1_SUB_PART_2017_1 USABLE
T1_CREATED_DATE_IDX T1_PART_2017 T1_SUB_PART_2017_3 USABLE
T1_CREATED_DATE_IDX T1_PART_2017 T1_SUB_PART_2017_2 USABLE
INDEX_NAME PARTITION_NAME SUBPARTITION_NAME STATUS
-------------------- -------------------- -------------------- --------
T1_CREATED_DATE_IDX T1_PART_2017 T1_SUB_PART_2017_4 USABLE