在生产环境中,业务初期数据量小,应用某些表未设计成分区表,随时间的推移,数据量越来越大,普通表的查询性能下降,需要把对表进行分区改表改造。在达梦数据库中,大表非分区表改造成分区表,建议优先使用dexp和dimp工具,因为操作可控,不对原表进行操作,随时可回退。
1、创建测试用表和测试数据
SQL> create table test1 (id int primary key ,name varchar(50)not null);
SQL> create index idx_name on test1 (name); --建索引
SQL> grant select on test1 to hr; --授予hr用户查询权限
2、插入模拟数据
begin
for i in 1 ..50000 loop
insert into test1 values (i,'aaaaaaaaaaa'||i);
end loop;
commit;
end;
/
3、停业务系统,使用dexp工具对原表导出数据(大表可以开启并行导出)
[dmdba@dmdb exp]$ dexp SYSDBA/Dameng123 file=/dm8/exp/test1_%u.dmp tables=test1 TABLE_PARALLEL=2 log=/dm8/exp/test1.log INCLUDE=CONSTRAINTS,INDEXES,ROWS,TRIGGERS,GRANTS
dexp V8
----- [2023-11-20 06:54:46]导出表:TEST1 -----
导出索引:IDX_NAME1
导出表对象权限...
表TEST1导出结束,共导出 50000 行数据
整个导出过程共花费 0.092 s
成功终止导出, 没有出现警告
4、创建分区表test2,约束和索引在插入数据完成后再创建
SQL> create table TT (id int,name varchar(50) not null )
partition by range (id)
interval(10000)
(partition p1 values less than (20000),
partition p2 values less than (30000),
partition p3 values less than (40000),
partition p4 values less than (50000),
partition p4 values less than (60000)
);
5、把test1导出的数据导入到test2
--导入时先不导入索引和约束,由于把test1映射到test2,之前导出权限没有导入
[dmdba@dmdb exp]$ dimp SYSDBA/hzgui123. file=/dm8/exp/test1_01.dmp tables=test1 TABLE_EXISTS_ACTION=TRUNCATE TABLE_PARALLEL=2 log=/dm8/exp/dimp_test2.log remap_table=test1:test2 rows=y CONSTRAINTS=N INDEXES=N
dimp V8
本地编码:PG_UTF8, 导入文件编码:PG_GB18030
----- [2023-11-20 07:01:16]导入表:TEST2 -----
[1/3]创建表已完成,导入表 TEST2 的数据中...
导入表 TEST2 的数据:50000 行被处理
[1/3]整个导入过程共花费 0.413 s
成功终止导入, 没有出现警告
6、添加主键约束和创建索引,对象权限授予
--添加主键约束
alter table "SYSDBA"."TEST2" add constraint "pk_test2_id" primary key("ID");
--创建索引(大表建索引可以开启并行)
CREATE INDEX "IDX_TEST2_NAME" ON "SYSDBA"."TEST2"("NAME" ASC) STORAGE(ON "MAIN", CLUSTERBTR) parallel 3;
--查询test1表对象权限赋予情况
SQL> select * from SYS.DBA_TAB_PRIVS where table_name='TEST1';
行号 GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY
---------- ------- ------ ---------- ------- --------- --------- ---------
1 HR SYSDBA TEST1 SYSDBA SELECT NO NO
--对象权限授予
SQL> grant select on test2 to hr; --授予hr用户查询权限
SQL> select * from SYS.DBA_TAB_PRIVS where table_name='TEST2';
行号 GRANTEE OWNER TABLE_NAME GRANTOR PRIVILEGE GRANTABLE HIERARCHY
---------- ------- ------ ---------- ------- --------- --------- ---------
1 HR SYSDBA TEST2 SYSDBA SELECT NO NO
7、表统计信息收集
CALL DBMS_STATS.GATHER_TABLE_STATS(OWNNAME=>'SYSDBA',TABNAME=>'TEST2',ESTIMATE_PERCENT=>100,CASCADE=>TRUE,METHOD_OPT=>'FOR ALL COLUMNS SIZE AUTO',DEGREE=>4,NO_INVALIDATE=>FALSE);
8、修改表名,分区改造完成,开启业务测试。
SQL> alter table test1 rename to test1bak;
操作已执行
已用时间: 9.746(毫秒). 执行号:8806.
SQL> alter table test2 rename to test1;
操作已执行
已用时间: 16.813(毫秒). 执行号:8807.
SQL>
总结:大表分区改造有很多方式,但在生产环境中,表的数据量很大,建议使用操作可控、时间可控、可回退的方式进行操作,确保在停业务的时间窗口内完成。
文章
阅读量
获赞