全面学习分区表及分区索引(13)--分隔表分区
如果你对我们前面讲到过的merge partition还有印象的话,那么学习Split partition也不会遇到什么障碍,split partition的功能与merge partition功能正好相反:后者是将两个全区合并成一个,前者则是将一个分区分隔成两个。其用途非常广泛,比如通常见你发现某个分区过大,你就可以通过这种方式将该分区分解成多个小分区,对我而言最常用到的,当然还是split maxvalue/default的分区。
该命令的语法针对不同分区会有不同的形式,
l For range partition:alter table tbname split partition ptname at (value) into (partition newpt1 tbs_clause,partition newpt2 tbs_clause);
l For list partition : alter table tbname split partition ptname values (v1,v2...vn) into (partition newpt1 tbs_clause,partition newpt2 tbs_clause);
上述两项,如果是操作子分区,则将partition关键字换成subpartition即可。旧分区中符合新定义值的记录会存储到指定的第一个分区中,其它的记录存储到第二个分区。
例如,range分区的示例:
SQL> select partition_name,high_value,tablespace_name from user_tab_partitions
2 where table_name= 'T_PART_RANGE';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ ------------------------------------ ------------------------------
T_RANGE_MAX MAXVALUE KARL_SPACE //注意这里!
T_RANGE_P1 10 PART01
我们将t_range_max分区分隔到两个分区中,小于20的存放新建分区t_range_p2(t_range_max已非原t_range_max鸟,只是名称相同而已),
其它数据存入t_range_max分区:
SQL> alter table t_part_range split partition t_range_max at (20) into (
2 partition t_range_p2 tablespace part02,
3 partition t_range_max tablespace part03);
Table altered
SQL> select partition_name ,high_value ,tablespace_name
2 from user_tab_partitions
3 where table_name ='T_PART_RANGE';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ -------------------------------------------------------------------------------- ------------------------------
T_RANGE_MAX MAXVALUE PART03
T_RANGE_P1 10 PART01
T_RANGE_P2 20 PART02
//奇迹果然诞生了。不知道发现没有。 t_range_max的tablespace 从 karl_space ---> part03
也就是说:split 操作是会产生IO的。
再来演示一个list分区的例子:
SQL> select partition_name ,high_value ,tablespace_name from user_tab_partitions
2 where table_name = 'T_PART_LIST';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ --------------------------- ------------------------------
T_LIST_P1 1 PART01
T_LIST_P2 2, 3 PART02
T_LIST_P3 default PART03
SQL> alter table t_part_list split partition t_list_p2 values (3)
2 into (partition t_part_p4 tablespace part03,
3 partition t_list_p2);
Table altered
SQL> select partition_name ,high_value ,tablespace_name from user_tab_partitions
2 where table_name = 'T_PART_LIST';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ --------------------------- ------------------------------
T_LIST_P1 1 PART01
T_LIST_P2 2 PART02
T_LIST_P3 default PART03
T_PART_P4 3 PART03
提示:
l split partition/subpartition不能用于hash分区或hash子分区(hash的话,直接用add partition就好了)
l split partition/subpartition视被分隔的分区数据量多少,可能需要花费不小的代价,相当于该分区数据的全扫描,我们也许可以形容为:full partition scan:),除非:
n Split后的两个分区中,至少有一个是空的,并且非空的那个分区的存储属性与split前的存储属性完全相同
n 如果split的分区包含lob字段,split后非空的那个分区中该字段的存储属性也必须与split前的存储属性完全相同。
这种情况下的split partition/subpartition也会非常高效,oracle会自动进行优化,此时的分区操作类似于add partition。
l 通常情况下,如果在执行split partition/subpartition时,如果没有指定update indexes子句,都会造成local和global索引的失效。注意,我们说的是通常,如果你split partition/subpartition的是个空分区,或者没有触发任何数据移动或变化,那么即使不加update indexes,也不会影响到索引。当然,保险起见,建议你还是执行完之后,查询一下数据字典,确认一下当前索引的状态。
如果你对我们前面讲到过的merge partition还有印象的话,那么学习Split partition也不会遇到什么障碍,split partition的功能与merge partition功能正好相反:后者是将两个全区合并成一个,前者则是将一个分区分隔成两个。其用途非常广泛,比如通常见你发现某个分区过大,你就可以通过这种方式将该分区分解成多个小分区,对我而言最常用到的,当然还是split maxvalue/default的分区。
该命令的语法针对不同分区会有不同的形式,
l For range partition:alter table tbname split partition ptname at (value) into (partition newpt1 tbs_clause,partition newpt2 tbs_clause);
l For list partition : alter table tbname split partition ptname values (v1,v2...vn) into (partition newpt1 tbs_clause,partition newpt2 tbs_clause);
上述两项,如果是操作子分区,则将partition关键字换成subpartition即可。旧分区中符合新定义值的记录会存储到指定的第一个分区中,其它的记录存储到第二个分区。
例如,range分区的示例:
SQL> select partition_name,high_value,tablespace_name from user_tab_partitions
2 where table_name= 'T_PART_RANGE';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ ------------------------------------ ------------------------------
T_RANGE_MAX MAXVALUE KARL_SPACE //注意这里!
T_RANGE_P1 10 PART01
我们将t_range_max分区分隔到两个分区中,小于20的存放新建分区t_range_p2(t_range_max已非原t_range_max鸟,只是名称相同而已),
其它数据存入t_range_max分区:
SQL> alter table t_part_range split partition t_range_max at (20) into (
2 partition t_range_p2 tablespace part02,
3 partition t_range_max tablespace part03);
Table altered
SQL> select partition_name ,high_value ,tablespace_name
2 from user_tab_partitions
3 where table_name ='T_PART_RANGE';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ -------------------------------------------------------------------------------- ------------------------------
T_RANGE_MAX MAXVALUE PART03
T_RANGE_P1 10 PART01
T_RANGE_P2 20 PART02
//奇迹果然诞生了。不知道发现没有。 t_range_max的tablespace 从 karl_space ---> part03
也就是说:split 操作是会产生IO的。
再来演示一个list分区的例子:
SQL> select partition_name ,high_value ,tablespace_name from user_tab_partitions
2 where table_name = 'T_PART_LIST';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ --------------------------- ------------------------------
T_LIST_P1 1 PART01
T_LIST_P2 2, 3 PART02
T_LIST_P3 default PART03
SQL> alter table t_part_list split partition t_list_p2 values (3)
2 into (partition t_part_p4 tablespace part03,
3 partition t_list_p2);
Table altered
SQL> select partition_name ,high_value ,tablespace_name from user_tab_partitions
2 where table_name = 'T_PART_LIST';
PARTITION_NAME HIGH_VALUE TABLESPACE_NAME
------------------------------ --------------------------- ------------------------------
T_LIST_P1 1 PART01
T_LIST_P2 2 PART02
T_LIST_P3 default PART03
T_PART_P4 3 PART03
提示:
l split partition/subpartition不能用于hash分区或hash子分区(hash的话,直接用add partition就好了)
l split partition/subpartition视被分隔的分区数据量多少,可能需要花费不小的代价,相当于该分区数据的全扫描,我们也许可以形容为:full partition scan:),除非:
n Split后的两个分区中,至少有一个是空的,并且非空的那个分区的存储属性与split前的存储属性完全相同
n 如果split的分区包含lob字段,split后非空的那个分区中该字段的存储属性也必须与split前的存储属性完全相同。
这种情况下的split partition/subpartition也会非常高效,oracle会自动进行优化,此时的分区操作类似于add partition。
l 通常情况下,如果在执行split partition/subpartition时,如果没有指定update indexes子句,都会造成local和global索引的失效。注意,我们说的是通常,如果你split partition/subpartition的是个空分区,或者没有触发任何数据移动或变化,那么即使不加update indexes,也不会影响到索引。当然,保险起见,建议你还是执行完之后,查询一下数据字典,确认一下当前索引的状态。