向表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.   

    楼主是想做以下的事吗?
    1.  向一张表插入海量数据,而且,依楼主的要求分析,这张表本身的数据量就很大。
    2.  想一条一条插入,判断一条插入一条。如果上述表达成立的话,不赞成楼主的方案,插入的同时进行判断。 
    因为,这样的效率太慢,别说1亿,100W的数据插入速度,就已经会让人抓狂了。建议考虑以下的方案,也是插入数据常用的方法
    1. 先插入数据
    2. 再进行滤重
        2.1 如果目标表里数据量非常大,滤重时进行特殊考虑,如,按分区一个一个进行滤重。
        2.2 另一种能想到的方式,先插入一张缓存表,缓存表 minus 目标表 (只在缓存表存在的记录) =>  插入目标表 即可。 也就是插入要分2步,当然,数据量巨大的情况下,也需要特殊考量(分区?)。总之,方法是有的,但重要的,还是实践,希望帮到楼主。
      

  2.   


    匿名块?是PL/SQL存储过程吗?
      

  3.   

    建议用第一种方法,采用PLSQL来逐笔做,并一笔一笔commit,不管怎样,必须先判断下field2是否有重复的存在,才插入,并且在插入的时候字段field1才能用seq.nextval,这样就不会出现跳号。
    如果用第二种设置为主键约束,那么你必然是在insert into 的时候就用到了seq.nextval,这样就有跳号现象存在了.
      

  4.   

    不知道你插入什么数据,亿条以上都不会重复。
    但1喽的方法可以考虑下。
    ------------------------
    1)在考虑效率的情况下,没有必要每次检查,这个毫无疑问是及其耗费时间的。
    2)从I/O考虑,你应该一次传送给SQL引擎尽量多的数据,而不是一次insert一条或者几条,应该是一次批量插入N条。 性能的瓶颈在于I/O跟不上CPU。这是一个可以按照情况来权衡的
      

  5.   

    没有看明白到底是什么意思,不过像这样插入行吗?insert into A (select 0,XXXX from b group by XXXX )
      

  6.   

    用 merge into 方法插入!
      

  7.   


    假如我采用先全部插入,再进行去重的方式,那么再插入数据时会引出如下问题:
    我有一个id列,要能够自增而且不断号。如果先插入全部数据再删除重复数据,会产生id字段的数据不连续;
      

  8.   

    如果能够设置足够的回滚段、临时表空间的话,可以使用下面的SQL来一次性插入,能够实现FIELD2除重和FIELD1连续的目的。
    如果亿条数据量过大,则把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;
      

  9.   

    insert into A 
    select seq.nextval,'XXX'
    from dual
    where not exists (select 1 from A where field2 = 'XXX');这样行不行
      

  10.   

    MERGE INTO table a
          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 ...)
      

  11.   

    MERGE INTO table a
          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 
      

  12.   

    我也认为merge应该更好一点吧。
      

  13.   


    小弟对复杂的SQL语句接触很少,请问其中的table b 与 a是同一个表吧?!