我需要向数据库中插入大量(50GB的随机数据),以便可以使用备份应用程序检查重复数据删除率。我写了一个如下的小程序
这需要1个多小时。我不知道如何提高性能,以便为insert语句获得良好的吞吐量。我已将SGA设置为16GB。
我是Oracle的新手。我不知道如何设置并行性来优化我的过程以获得良好的吞吐量。请帮忙。
alter session force parallel query parallel 4;
create table table_1(
col1 varchar2(400),
-- 50 columns like this
col50 varchar2(400));
create table table_2(
col1 varchar2(400),
-- 50 columns like this
col50 varchar2(400));
create table table_3(
col1 varchar2(400),
-- 50 columns like this
col50 varchar2(400));
create table table_4(
col1 varchar2(400),
-- 50 columns like this
col50 varchar2(400));
我的插入脚本:
Declare
rows_inserted number := 0;
Begin
Loop
Begin
INSERT INTO table_1(COL1, ..COL50)
VALUES(dbms_random.string('L', 400),..for all 50 values);
INSERT INTO table_2(COL1, ..COL50)
VALUES(dbms_random.string('L', 400),..for all 50 values);
INSERT INTO table_3(COL1, ..COL50)
VALUES(dbms_random.string('L', 400),..for all 50 values);
INSERT INTO table_4(COL1, ..COL50)
VALUES(dbms_random.string('L', 400),..for all 50 values);
--Only increment counter when no duplicate exception
rows_inserted := rows_inserted + 1;
--Exception When DUP_VAL_ON_INDEX Then Null;
End;
exit when rows_inserted = 10000;
End loop;
commit;
End;
/
我已经在安装在rhel 7 VM上的Oracle12c上尝试了此过程。 Vm具有32 GB内存和20GB交换内存以及16个vcpus。
这需要1个多小时,并且仍在运行。如何实现并行性并优化上述过程以获得良好的吞吐率?
答案 0 :(得分:2)
您正在循环内插入单行:这是一种很慢的处理方式。 SQL是一种基于集合的语言,集合操作是执行批量操作的最有效方式。另外,您还依赖于随机数据来提供重复项。控制它并保证比率。此外,当您的表没有唯一键时,如何获得DUP_VAL_ON_INDEX? (如果这样做的话,您将无法插入想要用于实验的重复项。)
更好的方法是使用批量sql:
INSERT INTO table_1(COL1, COL50)
select dbms_random.string('L', 400), dbms_random.string('L', 400)
from dual
connect by level <= 10000
/
INSERT INTO table_1(COL1, COL50)
select *
from table_1
where rownum <= 1000
/
这将为您在table_1
中提供11000行,其中1000行是重复的。重复第二次插入以增加重复项的数量。
应该不需要并行性。
我现在想要的是良好的吞吐量,无论有没有并行性,它都可以在30分钟内插入50 GB的数据。
但是,这条新信息改变了我的评估。并行运行此命令的最简单方法是为每个表构建单独的例程,并在单独的会话中运行每个例程。