分区表索引总结
一,分区索引分为2类:
1 global,它必定是Prefix的。不存在non-prefix的(当然这个是对分区索引来说的,非分区索引则不存在这种说法)
1.1 Prefix:索引的第一个列等于索引的分区列
2 local,它又分成2类:
2.1 prefix:索引的第一个列等于表的分区列(为什么是等于表的分区列?因为本地索引的索引分区列就是表的分区列)。
2.2 non-prefix:索引的第一个列不等于表的分区列。
二,global index
全局索引(global index):即可已分区,也可以不分区。可以建在分区表上,也可以建在非分区表上。全局索引必须是Prefix的,全局分区索引只能是B树索引
--另外oracle不会自动的维护全局分区索引,当我们在对表的分区做修改之后(如对分区作move,truncate,drop),如果对分区进行维护操作时不加上update global indexes的话,通常会导致全局索引的INVALDED,必须在执行完操作后REBUILD。
全局非分区索引:这个同普通索引差不多,这里就不多说了
全局分区索引:目前全局分区索引有两种分区方式range和hash
三,local index
本地索引(local index):本地只能建在分区表上,本地索引一定是分区索引,可以是prefix的也可以是non-prefix的(索引的分区结构同表的一致)
--对于本地索引,其索引分区的维护自动进行,就是说你add/drop/split/truncate表的分区时,本地索引会自动维护其索引分区。
--注意如果split分区,如果split出来的分区中没有数据那么local不会失效,否则local索引也会失效需要重建
--分区索引不能以一个整体重建(全局分区索引也是一样的)
四,全局非分区索引创建及维护
1. 建分区表
create table test ( OWNER, OBJECT_NAME, SUBOBJECT_NAME, OBJECT_ID, DATA_OBJECT_ID, OBJECT_TYPE) partition by range(object_id) ( partition p1 values less than(10000), partition p2 values less than(20000), partition p_max values less than(maxvalue) ) as select owner,object_name,subobject_name,object_id,data_object_id,object_type from dba_objects;
--查看分区表
select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION from dba_tab_partitions where table_name='TEST';
2. 建普通表
create table test_1 as select * from test;
3. 在分区表上建全局非分区索引
create index ind_test_id on test(object_id) global;
4. 在普通表上建全局非分区索引
create index ind_test_1_id on test_1(object_id) global;
5. 查看刚刚建的两个索引
select OWNER,INDEX_NAME,INDEX_TYPE,TABLE_OWNER,TABLE_NAME,TABLE_TYPE,PARTITIONED from dba_indexes where index_name like '%IND_TEST%'; OWNER INDEX_NAME INDEX_TYPE TABLE_OWNE TABLE_NAME TABLE_TYPE PAR ------------------------------ ------------------------------ --------------------------- ---------- -------------------- ----------- --- SCOTT IND_TEST_1_ID NORMAL SCOTT TEST_1 TABLE NO SCOTT IND_TEST_ID NORMAL SCOTT TEST TABLE NO
五,全局分区索引创建及维护
1. drop 上面建的两个索引
drop index IND_TEST_1_ID;
drop index IND_TEST_ID;
2.在分区表(test)上建全局分区索引
create index ind_test_id on test(object_id) global partition by range(object_id) ( partition p_ind1 values less than(5000), partition p_ind2 values less than(15000), partition p_indmax values less than(maxvalue) );
注意:
--全局分区索引的分区和表的分区是完全独立的(此处的索引分区结构就和表的分区结构不同)
--全局分区索引只能是Prefix的(否则会报ORA-14038错误)
--目前全局分区索引只支持range和hash分区方式
3. 在非分区表上(test_1)上建全局分区索引
create index ind_test_1_id on test_1(object_id) global partition by range(object_id) ( partition p_ind1 values less than(5000), partition p_ind2 values less than(15000), partition p_indmax values less than(maxvalue) );
--全局索引可以建在分区表上也可以建在非分区表上
4. 查看两个全局分区索引
SQL> select INDEX_OWNER,INDEX_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION,STATUS from dba_ind_partitions where index_name like '%IND_TEST%'; INDEX_OWNE INDEX_NAME PARTITION_NAME SUBPARTITION_COUNT HIGH_VALUE PARTITION_POSITION STATUS ---------- -------------------- ------------------------------ ------------------ ---------- ------------------ -------- SCOTT IND_TEST_1_ID P_IND1 0 5000 1 USABLE SCOTT IND_TEST_1_ID P_IND2 0 15000 2 USABLE SCOTT IND_TEST_1_ID P_INDMAX 0 MAXVALUE 3 USABLE SCOTT IND_TEST_ID P_IND1 0 5000 1 USABLE SCOTT IND_TEST_ID P_IND2 0 15000 2 USABLE SCOTT IND_TEST_ID P_INDMAX 0 MAXVALUE 3 USABLE
5. 全局分区索引的维护
因为全局索引的分区结构和表可以不一致,若不一致的情况下,对表分区的truncate,drop,add等操作会导致整个全局索引失效
可以在操作时加上UPDATE GLOBAL INDEXES,避免操作过后索引失效或在操作后重建
alter index IND_TEST_ID rebuild partition p_ind1 parallel 8;
--分区索引不能以一个整体重建,一个分区一个分区重建(所以全局分区索引维护任务要重一些)否则会报如下错误:
SQL> alter index ind_test_id rebuild; alter index ind_test_id rebuild * ERROR at line 1: ORA-14086: a partitioned index may not be rebuilt as a whole
alter index FILEINTER.IND_ODS_GAMEDT_BR_ACT_USERTEL rebuild partition P20140223 parallel 4 tablespace TBS_DS_DAY23;
alter index FILEINTER.IND_ODS_GAMEDT_BR_ACT_USERTEL rebuild subpartition PM20140125 parallel 5;组合分区索引重建
--以上为重建分区索引和重建组合分区索引方法
六,local index
1.创建local index
1)
create index ind_test_id on test(object_id) local ( partition p_ind1 tablespace users, partition p_ind2, partition p_ind3, partition p_indmax );
查看分区表
SQL> select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION from dba_tab_partitions where table_name='TEST'; TABLE_OWNE TABLE_NAME PARTITION_ SUBPARTITION_COUNT HIGH_VALUE PARTITION_POSITION ---------- -------------------- ---------- ------------------ ---------- ------------------ SCOTT TEST P2 0 20000 1 SCOTT TEST P3 0 30000 2 SCOTT TEST P4 0 40000 3 SCOTT TEST P_MAX 0 MAXVALUE 4
查看分区索引
SQL> select INDEX_OWNER,INDEX_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION,STATUS from dba_ind_partitions where index_name='IND_TEST_ID'; INDEX_OWNE INDEX_NAME PARTITION_ SUBPARTITION_COUNT HIGH_VALUE PARTITION_POSITION STATUS ---------- -------------------- ---------- ------------------ ---------- ------------------ -------- SCOTT IND_TEST_ID P_IND1 0 20000 1 USABLE SCOTT IND_TEST_ID P_IND2 0 30000 2 USABLE SCOTT IND_TEST_ID P_IND3 0 40000 3 USABLE SCOTT IND_TEST_ID P_INDMAX 0 MAXVALUE 4 USABLE
注意:
--本地分区索引的分区结构和分区表的分区是一致的,分区是一一对应的。
--我们可以指定索引的分区名和存储表空间(分区个数要同表分区个数一致)
2)
drop index ind_test_id;
create index ind_test_id on test(object_id) local;
查看分区表
select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION from dba_tab_partitions where table_name='TEST'; TABLE_OWNE TABLE_NAME PARTITION_ SUBPARTITION_COUNT HIGH_VALUE PARTITION_POSITION ---------- -------------------- ---------- ------------------ ---------- ------------------ SCOTT TEST P2 0 20000 1 SCOTT TEST P3 0 30000 2 SCOTT TEST P4 0 40000 3 SCOTT TEST P_MAX 0 MAXVALUE 4
查看分区索引
SQL> select INDEX_OWNER,INDEX_NAME,PARTITION_NAME,SUBPARTITION_COUNT,HIGH_VALUE,PARTITION_POSITION,STATUS from dba_ind_partitions where index_name='IND_TEST_ID'; INDEX_OWNE INDEX_NAME PARTITION_ SUBPARTITION_COUNT HIGH_VALUE PARTITION_POSITION STATUS ---------- -------------------- ---------- ------------------ ---------- ------------------ -------- SCOTT IND_TEST_ID P2 0 20000 1 USABLE SCOTT IND_TEST_ID P3 0 30000 2 USABLE SCOTT IND_TEST_ID P4 0 40000 3 USABLE SCOTT IND_TEST_ID P_MAX 0 MAXVALUE 4 USABLE
--不特别指定分区名和存储空间的话,默认同分区表一致
2.查看索引是local index还是global index
SQL> select LOCALITY from dba_part_indexes where index_name='IND_TEST_ID'; LOCALI ------ LOCAL
3.查看索引是PREFIXED or NONPREFIXED
SQL> select ALIGNMENT from dba_part_indexes where index_name='IND_TEST_ID'; ALIGNMENT ------------ PREFIXED