1、 说明
在系统建设初期,有些业务没有考虑数据量膨胀的问题,使用非分区表存储业务数据,随着时间推移,数据量越来越大,普通表出现各种性能问题,此时可以考虑将普通表转换为分区表,提升数据库的性能。
分区是指将表、索引等数据库对象划分为较小的可管理片段的技术,每一个片段称为分区子表或分区索引。一个表被分区后,对表的查询操作可以局限于某个分区进行,而不是整个表,这样可以大大提高查询速度。
将非分区表转换为分区表,有多种方案,常见的有使用逻辑导入导出的方式,或者使用分区交换技术,本文主要介绍分区交换技术。
2、注意事项
- 分区交换仅支持范围和列表分区,不支持HASH分区。
- 分区交换时不会进行数据校验,如果交换表的数据不符合分区范围,数据仍然会进入该分区。此时如果是范围分区可以使用split拆分分区,系统会自动对数据进行重组。
- 分区交换要求分区表与交换表具有相同的结构(相同的表类型、相同的列结构及相同的精度、相同的索引、相同的分布方式),否则会报“[-7000]:交换对象不匹配”的错误。
- 在生产环境中,为保证数据安全,建议对源表的数据备份后再做分区交换。
3、环境说明
操作系统:CentOS Linux release 7.7.1908 (Core)
数据库版本:DM Database Server 64 V8
4、操作方案
4.1、创建测试用户
SQL> create user shen identified by "Dameng123";
操作已执行
已用时间: 5.589(毫秒). 执行号:503.
SQL> grant resource to shen;
操作已执行
已用时间: 5.427(毫秒). 执行号:504.
4.2、创建非分区表
SQL> create table TEST_1 (id int,name varchar(20));
SQL> begin
for i in 1..500 loop
insert into TEST_1(id, name)
values(i, DBMS_RANDOM.RANDOM_STRING('U',5)||':'|| lpad(i,4, '0'));
end loop;
end;
/2 3 4 5 6 7
DMSQL 过程已成功完成
已用时间: 96.135(毫秒). 执行号:800.
SQL> SELECT COUNT(*) FROM TEST_1;
行号 COUNT(*)
---------- --------------------
1 500
已用时间: 0.277(毫秒). 执行号:806.
4.3、创建分区表
SQL> create table TEST_2 (
id int,
name varchar(20)
) partition by range(id) (
partition p1 values less than (100),
partition p2 values less than (200),
partition p3 values less than (300),
partition p4 values less than (400),
partition pN values less than (maxvalue));
操作已执行
已用时间: 116.693(毫秒). 执行号:801.
SQL>
4.4、执行分区交换
SQL> alter table TEST_2 exchange partition pN with table TEST_1;
分区交换完成后,原来的非分区表(TEST1)数据为空,数据会转移到分区表中(TEST2)。
SQL> SELECT COUNT(*) FROM TEST_1;
行号 COUNT(*)
---------- --------------------
1 0
已用时间: 0.386(毫秒). 执行号:808.
SQL> SELECT COUNT(*) FROM TEST_2;
行号 COUNT(*)
---------- --------------------
1 500
已用时间: 0.369(毫秒). 执行号:809.
SQL>
由于数据未进行校验,所有数据都进入了一个分区,即使数据不满足要求。
select 'p1' partition_name, count(*) num from TEST_2 partition(p1)
union all
select 'p2', count(*) from TEST_2 partition(p2)
union all
select 'p3', count(*) from TEST_2 partition(p3)
union all
select 'p4', count(*) from TEST_2 partition(p4)
union all
select 'pN', count(*) from TEST_2 partition(pN);
行号 PARTITION_NAME NUM
-------- -------------- --------------------
1 p1 0
2 p2 0
3 p3 0
4 p4 0
5 pN 500
已用时间: 0.493(毫秒). 执行号:810.
4.5、分区拆分
alter table TEST_2 split partition pN at (1000) into (partition p5, partition pmax);
6 rows got
已用时间: 0.491(毫秒). 执行号:811.
4.6、验证
select 'p1' partition_name, count(*) num from TEST_2 partition(p1)
union all
select 'p2', count(*) from TEST_2 partition(p2)
union all
select 'p3', count(*) from TEST_2 partition(p3)
union all
select 'p4', count(*) from TEST_2 partition(p4)
union all
select 'p5', count(*) from TEST_2 partition(p5)
union all
select 'pmax', count(*) from TEST_2 partition(pmax);
行号 PARTITION_NAME NUM
------- -------------- --------------------
1 p1 99
2 p2 100
3 p3 100
4 p4 100
5 p5 101
6 pmax 0
数据已均匀分布至各分区中。
更多学习资料请访问:https://eco.dameng.com
最后修改时间:2023-03-30 09:58:43
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




