我在Oracle中面临交换分区和子分区的问题。 请举例说明。
答案 0 :(得分:3)
请查看以下示例
CREATE TABLE DEPARTMENT
( DEPT_ID NUMBER(30,0) NOT NULL ENABLE,
IS_ACTIVE VARCHAR2(1 BYTE) NOT NULL ,
BUSINESS_DATE DATE NOT NULL ENABLE,
COMPANY_CODE VARCHAR2(4) DEFAULT 'C1' NOT NULL ,
CONSTRAINT PK_DEPARTMENT PRIMARY KEY (BUSINESS_DATE, COMPANY_CODE, DEPT_ID) ENABLE
)
PARTITION BY RANGE
(
BUSINESS_DATE
)
INTERVAL (
NUMTODSINTERVAL(1,'DAY')
)
SUBPARTITION BY LIST(COMPANY_CODE)
SUBPARTITION TEMPLATE
(
SUBPARTITION CMN_01 VALUES ('C1'),
SUBPARTITION CMN_02 VALUES ('C2'),
SUBPARTITION CMN_03 VALUES ('C3')
)
(
PARTITION DEFAULT_PART VALUES LESS THAN ('01-JAN-2012')
)
;
CREATE INDEX IDX1_DEPARTMENT ON DEPARTMENT (DEPT_ID, IS_ACTIVE);
CREATE TABLE TEMP_DEPARTMENT AS SELECT * FROM DEPARTMENT WHERE 1=2;
CREATE TABLE EMPLOYEE
( ID NUMBER(30,0) NOT NULL ENABLE,
DEPT_ID NUMBER(30,0) NOT NULL ENABLE,
BUSINESS_DATE DATE NOT NULL ENABLE,
COMPANY_CODE VARCHAR2(4) DEFAULT 'C1' NOT NULL,
CONSTRAINT PK_EMPLOYEE PRIMARY KEY (BUSINESS_DATE,COMPANY_CODE, ID) ENABLE,
CONSTRAINT FK1_EMPLOYEE_DEPT FOREIGN KEY (BUSINESS_DATE, COMPANY_CODE, DEPT_ID)
REFERENCES DEPARTMENT (BUSINESS_DATE, COMPANY_CODE, DEPT_ID) ENABLE NOVALIDATE
)
PARTITION BY RANGE
(
BUSINESS_DATE
)
INTERVAL (
NUMTODSINTERVAL(1,'DAY')
)
SUBPARTITION BY LIST(COMPANY_CODE)
SUBPARTITION TEMPLATE
(
SUBPARTITION CMN_01 VALUES ('C1'),
SUBPARTITION CMN_02 VALUES ('C2'),
SUBPARTITION CMN_03 VALUES ('C3')
)
(
PARTITION DEFAULT_PART VALUES LESS THAN ('01-JAN-2012')
);
- 将几个thousads记录插入到DEPARTMENT和EMPLOYEE表中,以获得少数分区及其所有子分区
select * from DEPARTMENT where BUSINESS_DATE='19-JAN-15' and COMPANY_CODE='C1';
select* from EMPLOYEE;
select * from all_tab_partitions where TABLE_OWNER='TEST' and
table_name='DEPARTMENT';
select * from ALL_TAB_SUBPARTITIONS where TABLE_OWNER='TEST' and
table_name='DEPARTMENT';
select * from all_tab_partitions where TABLE_OWNER='TEST' and
table_name='EMPLOYEE';
select * from ALL_TAB_SUBPARTITIONS where TABLE_OWNER='TEST' and
table_name='EMPLOYEE';
select * from TEMP_DEPARTMENT;
---交换并截断子分区
1)
ALTER TABLE DEPARTMENT EXCHANGE SUBPARTITION SYS_SUBP7356 WITH TABLE TEMP_DEPARTMENT WITHOUT VALIDATION UPDATE GLOBAL INDEXES; --Exchange sub partitioning
2)
truncate table TEMP_DEPARTMENT; --truncate temp exchange table
3)
ALTER TABLE DEPARTMENT TRUNCATE SUBPARTITION SYS_SUBP7356 DROP STORAGE UPDATE GLOBAL INDEXES; --truncate sub partitioning (sub partition name from ALL_TAB_SUBPARTITIONS table) with global index update
--Here above 1 to 3 steps execute for three sub partitioning
4)
ALTER TABLE DEPARTMENT DROP PARTITION SYS_P7359 UPDATE GLOBAL INDEXES;
- 使用全局索引更新
5)
ALTER TABLE EMPLOYEE TRUNCATE SUBPARTITION SYS_SUBP7360 DROP STORAGE UPDATE GLOBAL INDEXES;
; - 使用全局索引更新来截断子分区(来自ALL_TAB_SUBPARTITIONS表的子分区名称)
- 执行三个子分区,执行5个以上步骤
6)
ALTER TABLE EMPLOYEE DROP PARTITION SYS_P7363 UPDATE GLOBAL INDEXES;
- 使用全局索引更新从all_tab_partitions表中获取此分区名称
7)
- 更改索引PK_DEPARTMENT重建;
8)
- 更改索引IDX1_DEPARTMENT重建;
9)
- 更改索引PK_EMPLOYEE重建;
- 仅当在更改表时未使用UPDATE GLOBAL INDEXES进行交换,截断和删除分区或子分区时,才需要执行步骤7到9
10)
开始
dbms_stats.gather_table_stats(ownname=>'TEST', tabname=>'DEPARTMENT', granularity=>'ALL' ,no_invalidate=>FALSE);
dbms_stats.gather_table_stats(ownname=>'TEST', tabname=>'EMPLOYEE', granularity=>'ALL' ,no_invalidate=>FALSE);
end;
更新全局索引在更改表时用于交换,截断和删除分区或子分区,其中全局索引应用于该表,然后我们可以在此处并行地在同一个表上执行DML操作。 UPDATE GLOBAL INDEXES用于通过alter操作同时重建索引。 如果未使用UPDATE GLOBAL INDEXES,则不允许在同一个表上并行执行DML操作。对于全局索引,它将抛出ORA Exception以下。 ERROR从表中删除/交换/截断分区/子分区后执行插入操作时的消息: SQL错误:ORA-01502:索引'TEST.PK_DEPARTMENT'或此类索引的分区处于不可用状态 01502. 00000 - “index'%s。%s'或此类索引的分区处于不可用状态” *原因:已尝试访问索引或索引分区 已被直接加载或DDL标记为无法使用 手术 *操作:DROP指定的索引,或REBUILD指定的索引,或 重新使用不可用的索引分区
如果您不想使用UPDATE GLOBAL INDEXES并希望并行DML操作与清除,则使索引为Local(不得包含主键或唯一约束,因为它是默认创建的全局唯一索引)。它位于分区和子分区上,并引用默认表空间。 使用本地索引,您在该表上观察到缓慢插入。