2017-02-22 35 views
0

有了这个,我的意思是在表格中插入数百万条记录。我知道如何使用循环插入数据,但插入数百万个数据不会是一个好方法。什么是在Oracle中执行批量插入的最佳方式?

我有两个表

CREATE TABLE test1 
    (
    col1   NUMBER, 
    valu   VARCHAR2(30), 
    created_Date DATE, 
    CONSTRAINT pk_test1 PRIMARY KEY (col1) 
) 
/
CREATE TABLE test2 
    (
    col2   NUMBER, 
    fk_col1  NUMBER, 
    valu   VARCHAR2(30), 
    modified_Date DATE, 
    CONSTRAINT pk_test2 PRIMARY KEY (col2), 
    FOREIGN KEY (fk_col1) REFERENCES test1(col1) 
) 
/

请建议的方式插入一些伪记录高达离不开循环1万元左右。

+2

这些百万行的数据源是什么? –

+1

虚拟记录的随机程度如何,它需要多么实际 - 特别是在每个父母有多少个孩子等事情的情况下,如果儿童修改的日期必须晚于创建的日期,某些数据是否应该为空(以及什么比例)等?为两个表创建虚拟行相当容易;那么代表你真正嘲笑的真实数据会变得更加棘手。 –

+0

感谢您的评论,我们需要这个测试分页和负载测试,它不是像我想要一个有意义的数据,它只是一次插入。我们有一个父表和5个子表连接到它。让我为这个表格结构留下足够的时间。 –

回答

2

作为一种相当简单的方法,根据您的意见,这可能足以满足您的需求,您可以使用a hierarchical query生成虚拟数据。在这里,我使用绑定变量来控制创建的数量,并使一些逻辑更加清晰,但是您可以使用文字。

首先,父行:

var parent_rows number; 
var avg_children_per_parent number; 
exec :parent_rows := 5; 
exec :avg_children_per_parent := 3; 

-- create dummy parent rows 
insert into test1 (col1, valu, created_date) 
select level, 
    dbms_random.string('a', dbms_random.value(1, 30)), 
    trunc(sysdate) - dbms_random.value(1, 365) 
from dual 
connect by level <= :parent_rows; 

这可能会产生这样的行:

 COL1 VALU       CREATED_DA 
---------- ------------------------------ ---------- 
     1 rYzJBVI      2016-11-14 
     2 KmSWXfZJ      2017-01-20 
     3 dFSTvVsYrCqVm     2016-07-19 
     4 iaHNv       2016-11-08 
     5 AvAxDiWepPeONGNQYA    2017-01-20 

然后子行,这对于父母产生范围内的随机fk_col1

-- create dummy child rows 
insert into test2 (col2, fk_col1, valu, modified_date) 
select level, 
    round(dbms_random.value(1, :parent_rows)), 
    dbms_random.string('a', dbms_random.value(1, 30)), 
    trunc(sysdate) - dbms_random.value(1, 365) 
from dual 
connect by level <= :parent_rows * :avg_children_per_parent; 

可能会生成:

select * from test2; 

     COL2 FK_COL1 VALU       MODIFIED_D 
---------- ---------- ------------------------------ ---------- 
     1   2 AqRUtekaopFQdCWBSA    2016-06-30 
     2   4 QEczvejfTrwFw     2016-09-23 
     3   4 heWMjFshkPZNyNWVQG    2017-02-19 
     4   4 EYybXtlaFHkAYeknhCBTBMusGAkx 2016-03-18 
     5   4 ZNdJBQxKKARlnExluZWkHMgoKY  2016-06-21 
     6   3 meASktCpcuyi     2016-10-01 
     7   4 FKgmf       2016-09-13 
     8   3 JZhk       2016-06-01 
     9   2 VCcKdlLnchrjctJrMXNb   2016-05-01 
     10   5 ddL       2016-11-27 
     11   4 wbX       2016-04-20 
     12   1 bTfa       2016-06-11 
     13   4 QP        2016-08-25 
     14   3 RgmIahPL      2016-03-04 
     15   2 vhinLUmwLwZjczYdrPbQvJxU  2016-12-05 

那里的儿童人数为每个父变化:

select fk_col1, count(*) from test2 group by fk_col1 order by fk_col1; 

    FK_COL1 COUNT(*) 
---------- ---------- 
     1   1 
     2   3 
     3   3 
     4   7 
     5   1 

插入一百万行,而不是,只是改变了绑定变量。

如果您需要更多的儿童与父母之间的关系,所以修改日期总是在创建日期之后,您可以修改查询;例如:

insert into test2 (col2, fk_col1, valu, modified_date) 
select * 
from (
select level, 
    round(dbms_random.value(1, :parent_rows)) as fk_col1, 
    dbms_random.string('a', dbms_random.value(1, 30)), 
    trunc(sysdate) - dbms_random.value(1, 365) as modified_date 
from dual 
connect by level <= :parent_rows * :avg_children_per_parent 
) t2 
where not exists (
    select null from test1 t1 
    where t1.col1 = t2.fk_col1 and t1.created_date > t2.modified_date 
); 

您可能还需要非午夜时间(我通过trunc()调用设置一切午夜,基于列的名称是“日”而不是“日期时间”),或一些列的值无效;所以这可能只是你的一个起点。

+1

并且可能会抛出一个APPEND提示;)...插入/ * + APPEND * /进入测试... – BobC

+0

嗯...我怎么能忘记dbms_random ...,好方法Alex ...用这个我有一个更多的想法去插入所有,因为它有点类似于插入与选择...让我恢复你回我的观察...谢谢你,这将帮助我肯定:) –

相关问题