有一oracle项目需要如下
表TB_A  数量级 千万
表TB_B  数量级 千万现在要每月从TB_A 按条件提取部分数据 插入到 TB_B,数据正确性要求非常高。原本方案是存储过程直接用 "insert into tb_b (c1,c2,c3,c4) select c1,c2,c3,c4 from tb_a where ...";我想问是这每次操作数据量估计都超过几百万,这个语句执行会不会风险过高,效率过慢?请问哪位大侠有好的方案。

解决方案 »

  1.   

    有的高手说用nologging,但是加上nologging后 执行的时候说 ORA-00933:SQL命令未正确结束
      

  2.   

    用并行吧alter session enable parallel dml;
    insert /*+parallel(tb_b,2)*/ into tb_b (c1,c2,c3,c4) nologging select c1,c2,c3,c4 from tb_a where ....;
    commit;
      

  3.   

    比较奇怪为啥你加nologging会报错
    SQL> 
    SQL> CREATE TABLE test
      2  (a NUMBER(20));
     
    Table created
     
    SQL> 
    SQL> INSERT INTO test
      2  SELECT ROWNUM FROM dual CONNECT BY ROWNUM<1000;
     
    999 rows inserted
     
    SQL> 
    SQL> CREATE TABLE test1
      2  AS
      3  SELECT * FROM test NOLOGGING;
     
    Table created
     
    SQL> 
    SQL> INSERT INTO test1
      2  SELECT * FROM test NOLOGGING;
     
    999 rows inserted
     
    SQL> select count(*) from test1;
     
      COUNT(*)
    ----------
          1998
     
    SQL> 
      

  4.   

    另外效率的问题应该不用太担心。
    一个月一次,你可以把语句定时在半夜跑,对业务应该影响不大,而且这时候数据库资源占用少,速度也快。
    另外可以加上nologging以提升速度。
      

  5.   

    用insert写基本上是没有什么风险的,怕效率慢甚至可以加上append都没关系,oracle的恢复机制足够强大。
      

  6.   

    使用nologging,报错,怎么回事呢?SQL> insert into et.bi_pgs_refund
      2  select * from et.rt_et_sales_report t
      3  where t.trans_type = 'REFUND'
      4  nologging
      5  ;insert into et.bi_pgs_refund
    select * from et.rt_et_sales_report t
    where t.trans_type = 'REFUND'
    nologgingORA-00933: SQL 命令未正确结束
      

  7.   

    insert into et.bi_pgs_refund nologging
        select * from et.rt_et_sales_report t
        where t.trans_type = 'REFUND'
      

  8.   

    你可以先做好分区啊,像你这个情况 完全可以使用range partition,来做然后按分区insert 多方便啊。还不用全表扫描,只需要扫描单个分区即可。