基于Oracle11.2.04
当表中的数据量不断增大,查询数据的速度就会变慢,应用程序的性能就会下降,这时就应该考虑对表进行分区。表进行分区后,逻辑上仍然是一张完整的表,只是将表中的数据在物理上存放到多个表空间(物理文件上),这样查询数据时,不至于每次都扫描整张表。
官网的建议:
Range分区就是以列的值的范围来做为分区的划分条件,将记录放到列值所在的range分区中,因此在创建的时候,你需要指定基于的列,以及分区的范围值,如果某些记录暂时无法预测范围,可以创建maxvalue分区,所有不在指定范围内的记录都会被存储到maxvalue所在分区中,并且支持多列做为依赖列。
语法:
e.g.
create table table_name(
...
)
partition by range(column_name)
(
partition p1 values less than(values1),
partition p2 values less than(values2),
partition other values less than(maxvalue)
);
e.g. 按月自动创建分区。
create table table_name(
...
) tablespace tablespace_name
partition by range(partitions_field) interval(numtoyminterval(1, 'month'))
store in (tablespace_name)
(
partition partition_name_01 values less than(TIMESTAMP'2018-01-01 00:00:00') tablespace tablespace_name
)
range分区转换成interval分区
alter table table_name set interval(numtoyminterval(1, 'year'));
interval分区转换成range分区
alter table table_name set interval();
允许分区表的分区键是可更新
指当分区列的值更新后,就会把行数据从指定分区中delete掉,然后插入新的分区表。
alter table table_name enable row movement;
根据字段的hash值进行均匀分区,尽可能的实现各分区所散列的数据相等。通常是那些无法有效划分范围的表,使用hash分区,这样对于提高性能还是会有一定的帮助。列所在分区是依赖分区列的hash值自动分配,因此你并不能控制也不知道哪条记录会被放到哪个分区中,hash分区也可以支持多个依赖列。
Hash分区定义规则:
在定义Hash分区时,其分区数量应为2的N次方。
对于Hash分区,如果更改分区的数量,将导致所有数据在分区间的重新分布。
e.g.
create table table_name(
...
)
partition by hash(column_name)
(
partition p1,
partition p2,
partition p3,
...
);
List分区与range分区和hash分区都有类似之处,该分区与range分区相似的是也需要你指定列的值,但你必须明确指定值,并不能指定范围。与hash分区不同之处在于你能控制记录存储在哪个分区。但它的分区列只能有一个,不过它的单个分区对应的值可以是多个。你在分区时必须确定分区列可能存在的值,一旦插入的列值不在分区范围内,则插入、更新就会失败,因此通过建议使用List分区时,要创建一个default分区存储那些不在指定范围内的记录,类似range分区中的maxvalue分区。
create table table_name(
...
)
partition by list(column)
(
partition value1 values('1'),
partition value2 values('2'),
...
)
注意:对于同一张组合分区表而言,子分区的名字不能相同,即使不在相同的分区里。
create table table_name(
...
)
partition by range(column1)
subpartition by hash(column2)
(
partition p1 values less than(oneValue)
(
subpartition sp1,
subpartition sp2,
...
),
partition p2 values less than(maxvalue)
(
subpartition sp3,
subpartition sp4,
...
)
);
2… 范围-列表分区
e.g.
create table table_name(
...
)
partition by range(column2) subpartition by list(column3)
(
partition p1 values less than('value1')
(
subpartition one values('01', '11'),
subpartition two values('02', '22'),
...
),
partition p2 values less than('value2')
(
subpartition three values('03', '33'),
...
),
...
)
分区索引分为两类,一类叫local,一类叫global。
是在全局建立索引,这种方式和建立不建立分区一样一般不使用。
还有一种就是自定义数据区间的索引,也叫做前缀索引,不过自定义区域值必须有maxvalue。
global自定义全局(前缀索引)索引方式方法:
create index index_namme on table(field) global
partition by range(field) (
partition parrtition_name1 values less than(values),
partition partition_name2 values less thhan(maxvalue)
)
global全局索引:
create index index_name on tablle(fiield) global;
在每个分区建立索引。需要注意,在分区上建立的索引必须是分区字段。
create index index_name on table(field) local;
select * from user_ind_partitions;
修改分区信息状态后需要重新收集分区表的统计信息。
selecct table_name, partitioning_type, partition_count, status
from dba_part_tables
where table_name = 'table_name'
select * from table_name partition(partition_name)
sellect a.table_name, partitioning_type, partition_name, high_value, num_rows
from user_part_tables a, user_tab_parrtitions b
where a.table_name = b.table_name
analyze table test_range_partition coompute statistics;
注意:当分区表存在默认条件分区,如:range分区表的maxvalue分区,list分区表的default分区,此时增加分区操作会报错。
可以删除原默认条件分区,待增加分区后,再重新添加默认条件分区. 不过默认条件的分区的删除,其数据不会重分布到其他分区,而是删除数据。因此在生产环境使用需要慎重。
或者使用拆分分区(split)的方式。
对于分区的删除操作,需要注意,在删除分区后,分区所记录的数据,不会重新分配到其他分区中,而是被删除。慎用。
alter table table_name drop partition partition_name;
移动分区所在的表空间,不过对于组合分区,无法直接移动分区。需要先修改子分区的所在表空间,然后再修改分区的分区属性。
alter table table_name move partition partition tablespace tablespace_name;
截断分区维护操作,相对于传统的delete操作,删除数据的效率会更高。而且会降低高水位线。
alter table table_name truncate partition partition_name;
在目标分区被拆分后,被拆分的分区会按照拆分规则,将数据进行重分布。
alter table table_name split partition partition_name at (values) into (
partition partition_name,
...);
???
合并分区操作,主要是将不同的分区,通过分区的合并,进行整合。
需要注意:
alter table table_name merget partitions partition_name1, partition_name2 [,...] into partition_name_merge;
交换分区技术,主要是将一个非分区表的数据同一个分区表的一个分区进行数据交换。支持双向交换,既可以从分区表的分区中迁移到非分区表,也可以从非分区表迁移到分区表的分区中。
原则上,非分区表的结构、数据分布等,要符合分区表的目标分区的定义规则。解决办法是通过without validation子句,可以避免数据校验,而交换成功。但会存在与分区规则相悖的数据,因此在生产环境使用需要慎重。
技术方案扩展思路:若打算采用交换分区的方法,以实现非分区表到分区表的转换,可以采用先创建一个只有默认条件的单一分区的分区表,在分区交换数据后,根据实际需要,通过前面提到的“拆分分区”的方法进行分区操作。
alter table table_name_has_partitions exchange partition partition_name with table table_name_no_partitions;
收缩分区维护操作,仅仅可以在hash分区以及组合分区的hash子分区上进行使用。通过使用收缩分区技术,可以收缩当前hash分区的分区数量。对于hash分区的数据,在收缩过程中,oracle会自动完成数据在分区间的重分布。
alter table table_name coalesce partition;
需要注意:当hash分区中只有一个分区时,此时无法进行收缩操作。