我搜索了很多,但还没找到我的问题的答案。
所以,我必须在不同的表中生成大量数据(数百万行),这个脚本应该快速。
现在让我们来谈谈3个特定的表,其中有id行:
在第三个表格中,名为所有权,我必须"合并"这些ID具有一些特定的费率:
重要事项:
注意:以下是我如何将行生成为汽车(所有者类似)
(它将生成v_custom_unit件行,此单位是根据我的费率计算的给出几行之前(对于100个单位车主,将生成210个单位车辆和210个单位所有权),然后我使用for循环来乘以行):
insert /*+ APPEND */ into Cars(
carId
, carType
, ...
)
select /*+ PARALLEL */
seq_carid.nextval as carId
, REGEXP_SUBSTR( 'Suziki,Toyota,Subaru,Saab,Hyundai,Opel,Volkswagen', '([^,]+)', 1, ROUND(DBMS_RANDOM.VALUE(1,7)) ) as carType
, ...
from dual
connect by level <= v_custom_unit;
乘法是这样的:
FOR i in 1..v_forSteps LOOP
EXECUTE IMMEDIATE '
insert /*+ APPEND */ into Cars (
carId,
, carType,
, ...
)
SELECT /*+ PARALLEL */
seq_carid.nextval as carId,
, carType
, ...
FROM Cars
WHERE ROWNUM <= ' || v_custom_unit;
COMMIT;
END LOOP;
下一步是生成所有权行:
insert /*+ APPEND */ into Ownership (
ownerId
, carId
, date_bought
)
select /*+ PARALLEL */
1
, c.carId
, some_random_date as date_bought
from Cars c;
我的问题出现了:每辆车都在所有权中,ownerId = 1。
我的问题是:如何在一次更新中更新具有不同所有者值的所有权表(并且可能维持费率(50%-20%-10%-10%-10) %))吗
答案 0 :(得分:0)
其中一种方法:
insert into ownership (ownerid, carid, bought)
with t(oid, cid, cnt) as (
select 1, 1, 1 from dual
union all
select case when oid <= 5
or oid <= 7 and cnt >= 2
or oid <= 8 and cnt >= 3
or oid <= 9 and cnt >= 4
or oid <= 10 and cnt >= 5 then oid + 1
else oid
end,
cid + 1,
case when oid <= 5
or oid <= 7 and cnt >= 2
or oid <= 8 and cnt >= 3
or oid <= 9 and cnt >= 4
or oid <= 10 and cnt >= 5 then 1
else cnt + 1
end
from t where cid < 21)
select oid, cid, trunc(sysdate) - round(dbms_random.value * 1000) from t
这是10个车主和21辆车的演示。不确定效率,但这只是一个递归查询。需要Oracle 11g。
测试表和输出:
create table ownership (carid number(6), ownerid number(6), bought date);
CARID OWNERID BOUGHT
------- ------- -----------
1 1 2013-12-29 -- one car
2 2 2015-12-16
3 3 2014-04-04
4 4 2013-12-17
5 5 2013-11-20
6 6 2014-04-04 -- two cars
7 6 2015-09-05
8 7 2013-12-19
9 7 2016-01-02
10 8 2015-08-22 -- three
11 8 2014-03-05
12 8 2016-07-14
13 9 2015-09-02 -- four
14 9 2015-08-28
15 9 2015-06-04
16 9 2014-04-20
17 10 2016-08-07 -- five
18 10 2015-07-16
19 10 2014-12-08
20 10 2016-04-26
21 10 2014-05-30
答案 1 :(得分:0)
如果您只需要用测试数据填充空表并且性能很重要,您可以考虑将dml和序列放在一边。为了维持利率,您可以在余数的基础上使用函数ownerId = f(carId)
。
--drop table owners;
--drop table cars;
--drop table ownership;
create table owners as
select level n
from dual
connect by level < 1000*1000*1;
create table cars as
select level n
from dual
connect by level < 2100*1000*1;
create table ownership as
select level cid,
10*trunc(level/21) + case
when mod(level, 21) between 0 and 4 then mod(level, 21)
when mod(level, 21) between 5 and 6 then 5
when mod(level, 21) between 7 and 8 then 6
when mod(level, 21) between 9 and 11 then 7
when mod(level, 21) between 12 and 15 then 8
when mod(level, 21) between 16 and 20 then 9
end oid
from dual
connect by level < 2100*1000*1;
并检查结果:
with
cars_by_owner as (
select oid, count(*) cnt
from ownership
group by oid),
owners_by_cars_count as (
select cnt, count(*) c, grouping(cnt) rg
from cars_by_owner
group by rollup(cnt))
select f.cnt "cars count",
f.c "owners count",
round(f.c/s.c*100) "%"
from owners_by_cars_count f
join owners_by_cars_count s
on f.rg = 0 and s.rg = 1
cars_count owners_count %
1 499999 50
2 200000 20
3 100000 10
4 100000 10
5 100000 10
创建1M所有者2.1M汽车并填写ownership
表需要几秒钟。
如果您遇到ORA-30009,您可能会生成一个带有正数而不是connect by level
的辅助表。