向表A(field1,field2)中插入数据,其中字段field1为自动增长的(我使用了序列自增的方式,如insert into A values(seq.nextval,'XXX')),而字段field2的值是不能重复的(其实是多个字段,这里做了简化)。一次性要插入上亿条数据。
我使用的方法:
1)select count(*) from A where field2=‘XXX’;如果count(*) >=1,就中不再执行插入任务;
2)将field2字段(其实是多个字段)设为主键,插入数据时由Oracle自行进行主键约束判断;问题:
a)请问各位还有更好的方法吗?
b)另外,我使用方法2的时候,由于字段field1做了序列自增,导致即使主键约束使得无法插入重复数据,但是field1字段的值还是自增了,表现为下一条数据成功插入时,其field1字段的值与上一个值不连续。有没有一个方法能够使得field1字段的值是自动增长的(多线程插入),同时在遇到重复值不进行插入时该字段不自增?
我使用的方法:
1)select count(*) from A where field2=‘XXX’;如果count(*) >=1,就中不再执行插入任务;
2)将field2字段(其实是多个字段)设为主键,插入数据时由Oracle自行进行主键约束判断;问题:
a)请问各位还有更好的方法吗?
b)另外,我使用方法2的时候,由于字段field1做了序列自增,导致即使主键约束使得无法插入重复数据,但是field1字段的值还是自增了,表现为下一条数据成功插入时,其field1字段的值与上一个值不连续。有没有一个方法能够使得field1字段的值是自动增长的(多线程插入),同时在遇到重复值不进行插入时该字段不自增?
解决方案 »
- hi,谁PL/SQL玩的好
- 结果中的字段内容在新表中用字段表示,用sql能否实现?
- 为什么这个语句在SQL下能执行,而写到FUNCTIONS里就编译不能通过呢?
- 高难度SQL查询。。。解决的多送分。。
- 有没有人感觉自己公司的开发还算规范,认为还是可以拿出来说的?
- 查看ORACLE程序包中函数内容(急)
- [PRO C/C++][CLOB]pro c 读取clob为什么读出的是空的呢?
- ora-12560:TNS:协议适配器错误?菜问题。
- 请问:怎么编写存储过程或者.sql文件来编译oracle某用户下的所有存储过程?先谢了
- oracle中怎么设置sessoin中执行一条命令时最多影响到的记录行数
- C# ODP.NET 11.2访问 oracle 中文乱码
- 我想在代码中加个exception请问怎么加?
1. 向一张表插入海量数据,而且,依楼主的要求分析,这张表本身的数据量就很大。
2. 想一条一条插入,判断一条插入一条。如果上述表达成立的话,不赞成楼主的方案,插入的同时进行判断。
因为,这样的效率太慢,别说1亿,100W的数据插入速度,就已经会让人抓狂了。建议考虑以下的方案,也是插入数据常用的方法
1. 先插入数据
2. 再进行滤重
2.1 如果目标表里数据量非常大,滤重时进行特殊考虑,如,按分区一个一个进行滤重。
2.2 另一种能想到的方式,先插入一张缓存表,缓存表 minus 目标表 (只在缓存表存在的记录) => 插入目标表 即可。 也就是插入要分2步,当然,数据量巨大的情况下,也需要特殊考量(分区?)。总之,方法是有的,但重要的,还是实践,希望帮到楼主。
匿名块?是PL/SQL存储过程吗?
如果用第二种设置为主键约束,那么你必然是在insert into 的时候就用到了seq.nextval,这样就有跳号现象存在了.
但1喽的方法可以考虑下。
------------------------
1)在考虑效率的情况下,没有必要每次检查,这个毫无疑问是及其耗费时间的。
2)从I/O考虑,你应该一次传送给SQL引擎尽量多的数据,而不是一次insert一条或者几条,应该是一次批量插入N条。 性能的瓶颈在于I/O跟不上CPU。这是一个可以按照情况来权衡的
假如我采用先全部插入,再进行去重的方式,那么再插入数据时会引出如下问题:
我有一个id列,要能够自增而且不断号。如果先插入全部数据再删除重复数据,会产生id字段的数据不连续;
如果亿条数据量过大,则把FIELD2排序后,自己分段放入到TEST_TAB中即可。
如果目标表A中已经包含了TEST_TAB中部分数据,则还需要使用not exists来过滤,记得加索引。INSERT INTO A
(FIELD1,FIELD2)
SELECT SEQ.NEXTVAL, FIELD2
FROM (SELECT /*+ PARALLEL(A,4)*/
A.FIELD2,
ROW_NUMBER() OVER(PARTITION BY A.FIELD2 ORDER BY 1 DESC NULLS LAST) AS RN
FROM TEST_TAB A) B
WHERE B.RN = 1;
select seq.nextval,'XXX'
from dual
where not exists (select 1 from A where field2 = 'XXX');这样行不行
USING (SELECT cols1,cols2,cols3 ...
FROM tableb) b
ON (a.cols1 = b.cos1)
WHEN NOT MATCHED THEN
INSERT (cols1,cols2,cols3 ...)
VALUES (b.cols1,cols2,cols3 ...)
USING (SELECT cols1,cols2,cols3 ...
FROM tableb) b
ON (a.cols1 = b.cos1)
WHEN NOT MATCHED THEN -不存在,就插入
INSERT (cols1,cols2,cols3 ...)
VALUES (b.cols1,cols2,cols3 ...)
WHEN MATCHED THEN --存在就UPDATE,这个你可以不要的
UPDATE
SET a.cols1 = b.cols1, a.cols2 = b.cols2,
a.cols3 = b.cols3 ...
where a.cols1 = b.cols1
小弟对复杂的SQL语句接触很少,请问其中的table b 与 a是同一个表吧?!