`
阅读更多

http://www.oracleonlinux.cn/2012/09/oracle-splitting-partitions/

 

 

本文简单记录在Oracle 10g数据库上对范围分区表的Splitting Partitions测试过程和结论,并不涉及到Oracle数据库中分区技术的详细描述。

1 测试环境及平台:

OS:

 

1 [root@localhost ~]# uname -rm
2 2.6.18-164.el5 x86_64
3 [root@localhost ~]#

Oracle:

01 SQL> select * from v$version;
02   
03 BANNER
04 ----------------------------------------------------------------
05 Oracle Database 10g Enterprise Edition Release 10.2.0.5.0 - 64bi
06 PL/SQL Release 10.2.0.5.0 - Production
07 CORE    10.2.0.5.0      Production
08 TNS for Linux: Version 10.2.0.5.0 - Production
09 NLSRTL Version 10.2.0.5.0 - Production
10   
11 SQL>

2 创建范围分区表:

01 SQL> show user;
02 USER is "SYS"
03 SQL> create table part_range(id number,name varchar2(30))
04   2  partition by range(id)
05   3  (partition partmax values less than (maxvalue))
06   4  tablespace users;
07   
08 Table created.
09   
10 SQL>

3 插入测试数据:

1 SQL> insert into part_range select object_id,object_name from dba_objects
2   where object_id<2000;
3   
4 1953 rows created.
5   
6 SQL>

4 在分区表part_range上创建2种分区索引:

本地分区索引【Locally partitioned index】

1 SQL> create index part_range_id_idx on part_range(id) local;
2   
3 Index created.
4   
5 SQL>

全局分区索引【Globally partitioned index】

1 SQL> create index part_range_name_idx on part_range(name) tablespace users;
2   
3 Index created.
4   
5 SQL>

5 查看分区表信息:

1 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions
2   where table_name='PART_RANGE';
3   
4 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
5 ------------------------------ ------------------------------ ------------------------------
6 PART_RANGE                     PARTMAX                        USERS
7   
8 SQL>

6 查看索引信息:

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions
02   where index_name='PART_RANGE_ID_IDX';
03   
04 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
05 ------------------------------ ------------------------------ ------------------------------ --------
06 PART_RANGE_ID_IDX              PARTMAX                        USERS                          USABLE
07   
08 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes
09   where table_name='PART_RANGE';
10   
11 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
12 ------------------------------ ------------------------------ ------------------------------ -------- ---
13 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
14 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          VALID    NO
15   
16 SQL>

7 对分区表part_range执行Splitting partitions【分区分裂】操作:

1 SQL> alter table part_range split partition partmax at (2000) 
2   into (partition p1,partition partmax);
3   
4 Table altered.
5   
6 SQL>

注意,这里的分区分裂操作临界值是2000,即id<2000的记录将全部重组到p1分区,而partmax分区将为空,即0记录

01 SQL> select count(*) from part_range;
02   
03   COUNT(*)
04 ----------
05       1953
06   
07 SQL> select count(*) from part_range partition(p1);
08   
09   COUNT(*)
10 ----------
11       1953
12   
13 SQL> select count(*) from part_range partition(partmax);
14   
15   COUNT(*)
16 ----------
17          0
18   
19 SQL>

8 再次分别查看分区表、索引信息:

分区表:

1 SQL>  select table_name,partition_name,tablespace_name from user_tab_partitions
2   2   where table_name='PART_RANGE';
3   
4 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
5 ------------------------------ ------------------------------ ------------------------------
6 PART_RANGE                     PARTMAX                        USERS
7 PART_RANGE                     P1                             USERS
8   
9 SQL>

索引信息:

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions
02   where index_name='PART_RANGE_ID_IDX';
03   
04 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
05 ------------------------------ ------------------------------ ------------------------------ --------
06 PART_RANGE_ID_IDX              P1                             USERS                          USABLE
07 PART_RANGE_ID_IDX              PARTMAX                        USERS                          USABLE
08   
09 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes
10   where table_name='PART_RANGE';
11   
12 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
13 ------------------------------ ------------------------------ ------------------------------ -------- ---
14 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
15 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          VALID    NO
16   
17 SQL>

小结:对于分区分裂之后,如果包含有空分区的话,那么对于本地分区索引和全局分区索引都是可用的。这种分区分裂的方式通常也叫做快速分裂【Fast Splitting】,索引不需要rebuild。

9 如果在上述步骤7中,执行的分区分裂操作如下:

1 SQL> alter table part_range split partition partmax at (1000)
2   into (partition p1,partition partmax);
3   
4 Table altered.
5   
6 SQL>

即分区分裂操作临界值是1000id<1000的记录将重组到p1分区,id>=1000的记录将重组到partmax分区。也就是此时,分裂出来的p1和partmax这两个分区均不为空。

01 SQL> select count(*) from part_range;
02   
03   COUNT(*)
04 ----------
05       1953
06   
07 SQL> select count(*) from part_range partition(p1);
08   
09   COUNT(*)
10 ----------
11        953
12   
13 SQL> select count(*) from part_range partition(partmax);
14   
15   COUNT(*)
16 ----------
17       1000
18   
19 SQL>

那么,查看到的分区表、索引信息如下:

分区表:

1 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions
2   where table_name='PART_RANGE';
3   
4 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
5 ------------------------------ ------------------------------ ------------------------------
6 PART_RANGE                     PARTMAX                        USERS
7 PART_RANGE                     P1                             USERS
8   
9 SQL>

索引信息:

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions
02   where index_name='PART_RANGE_ID_IDX';
03   
04 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
05 ------------------------------ ------------------------------ ------------------------------ --------
06 PART_RANGE_ID_IDX              P1                             USERS                          UNUSABLE
07 PART_RANGE_ID_IDX              PARTMAX                        USERS                          UNUSABLE
08   
09 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes
10   where table_name='PART_RANGE';
11   
12 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
13 ------------------------------ ------------------------------ ------------------------------ -------- ---
14 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
15 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          UNUSABLE NO
16   
17 SQL>

小结:对于分区分裂之后,如果不包含空分区的话,那么对于本地分区索引和全局分区索引都将不可用,索引的状态都变为UNUSABLE。均需要重建

01 SQL> alter index PART_RANGE_ID_IDX rebuild partition p1;
02   
03 Index altered.
04   
05 SQL> alter index PART_RANGE_ID_IDX rebuild partition partmax;
06   
07 Index altered.
08   
09 SQL> alter index PART_RANGE_NAME_IDX rebuild;
10   
11 Index altered.
12   
13 SQL>

重建之后,本地分区索引、全局分区索引信息,已由UNUSABLE变为USABLE

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions
02   where index_name='PART_RANGE_ID_IDX';
03   
04 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
05 ------------------------------ ------------------------------ ------------------------------ --------
06 PART_RANGE_ID_IDX              P1                             USERS                          USABLE
07 PART_RANGE_ID_IDX              PARTMAX                        USERS                          USABLE
08   
09 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes
10   where table_name='PART_RANGE';
11   
12 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
13 ------------------------------ ------------------------------ ------------------------------ -------- ---
14 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
15 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          VALID    NO
16   
17 SQL>

当然,如果在分裂分区的同时带上UPDATE INDEXES的话,可以在分裂分区的同时重建索引【包含本地分区索引和全局分区索引,状态均为USABLE、VALID】:

1 SQL> alter table part_range split partition partmax at (1000) into (partition p1,partition partmax) update indexes;
2   
3 Table altered.
4   
5 SQL>

分裂分区之后,表信息:

1 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions
2   where table_name='PART_RANGE';
3   
4 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
5 ------------------------------ ------------------------------ ------------------------------
6 PART_RANGE                     PARTMAX                        USERS
7 PART_RANGE                     P1                             USERS
8   
9 SQL>

索引信息:

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions where index_name='PART_RANGE_ID_IDX';
02   
03 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
04 ------------------------------ ------------------------------ ------------------------------ --------
05 PART_RANGE_ID_IDX              P1                             USERS                          USABLE
06 PART_RANGE_ID_IDX              PARTMAX                        USERS                          USABLE
07   
08 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes where table_name='PART_RANGE';
09   
10 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
11 ------------------------------ ------------------------------ ------------------------------ -------- ---
12 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
13 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          VALID    NO
14   
15 SQL>

而如果在分裂分区的同时带上UPDATE GLOBAL INDEXES的话,可以在分裂分区的同时重建全局分区索引【不包含本地分区索引,只有全局分区索引状态为VALID】,而本地分区索引需要重建:

1 SQL> alter table part_range split partition partmax at (1000) into (partition p1,partition partmax) update global indexes;
2   
3 Table altered.
4   
5 SQL>

分裂分区之后,表信息:

1 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions
2   where table_name='PART_RANGE';
3   
4 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
5 ------------------------------ ------------------------------ ------------------------------
6 PART_RANGE                     PARTMAX                        USERS
7 PART_RANGE                     P1                             USERS
8   
9 SQL>

索引信息:

01 SQL> select index_name,partition_name,tablespace_name,status from user_ind_partitions where index_name='PART_RANGE_ID_IDX';
02   
03 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
04 ------------------------------ ------------------------------ ------------------------------ --------
05 PART_RANGE_ID_IDX              P1                             USERS                          UNUSABLE
06 PART_RANGE_ID_IDX              PARTMAX                        USERS                          UNUSABLE
07   
08 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes where table_name='PART_RANGE';
09   
10 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
11 ------------------------------ ------------------------------ ------------------------------ -------- ---
12 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
13 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          VALID    NO
14   
15 SQL>

需要注意的是,在分裂分区的同时重建索引,将会消耗更多时间来完成分裂工作,以及消耗更多的系统资源。如果系统资源较为充足的话,可以考虑带上UPDATE INDEXES选项。

10 最后,再看看另外一种比较特殊的情况。在分裂分区的时候,如果将新分区指向新的表空间【由USERS到EXAMPLE表空间】的话,并且分裂之后,包含空分区的情况。即,分裂的语句如下:

01 SQL> alter table part_range split partition partmax at (2000)
02   into (partition p1 tablespace example,partition partmax tablespace example);
03   
04 Table altered.
05   
06 SQL> select count(*) from part_range;
07   
08   COUNT(*)
09 ----------
10       1953
11   
12 SQL> select count(*) from part_range partition(p1);
13   
14   COUNT(*)
15 ----------
16       1953
17   
18 SQL> select count(*) from part_range partition(partmax);
19   
20   COUNT(*)
21 ----------
22          0
23   
24 SQL>

那么可以看到分区表:

1 SQL> select table_name,partition_name,tablespace_name from user_tab_partitions where table_name='PART_RANGE';
2   
3 TABLE_NAME                     PARTITION_NAME                 TABLESPACE_NAME
4 ------------------------------ ------------------------------ ------------------------------
5 PART_RANGE                     PARTMAX                        EXAMPLE
6 PART_RANGE                     P1                             EXAMPLE
7   
8 SQL>

索引分区信息:

01 SQL>  select index_name,partition_name,tablespace_name,status from user_ind_partitions where index_name='PART_RANGE_ID_IDX';
02   
03 INDEX_NAME                     PARTITION_NAME                 TABLESPACE_NAME                STATUS
04 ------------------------------ ------------------------------ ------------------------------ --------
05 PART_RANGE_ID_IDX              P1                             EXAMPLE                        UNUSABLE
06 PART_RANGE_ID_IDX              PARTMAX                        EXAMPLE                        USABLE
07   
08 SQL> select index_name,table_name,tablespace_name,status,partitioned from user_indexes where table_name='PART_RANGE';
09   
10 INDEX_NAME                     TABLE_NAME                     TABLESPACE_NAME                STATUS   PAR
11 ------------------------------ ------------------------------ ------------------------------ -------- ---
12 PART_RANGE_ID_IDX              PART_RANGE                                                    N/A      YES
13 PART_RANGE_NAME_IDX            PART_RANGE                     USERS                          UNUSABLE NO
14   
15 SQL>

小结:在分裂分区的时候,如果将新分区指向新的表空间的话,并且分裂之后,即使包含空分区的情况下,只有新空分区的本地索引不需要重建,而含有数据的新分区的本地分区索引以及全局分区索引均需重建。这有别于快速分裂,或者说是快速分裂的一种特殊情况

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics