【问题标题】:Inserting large data set using procedure in Oracle Database在 Oracle 数据库中使用过程插入大型数据集
【发布时间】:2017-01-20 15:28:56
【问题描述】:

我有一个表AA包含6列(a,b,c,d,e,f),有2亿条记录有a,bc 作为复合键。 a 列或b 列或c 列可能有多个重复条目。 c 列有多个条目,每个条目有 ab

我必须将a,b,d,e,fc 不存在)列的值复制到另一个具有列a,@ 的表 AB 中987654343@,d,e,fa,b,d 作为复合键,因此列 d 可以具有最大值 2 和 a,@98 ,d 最多应该有 2 个条目。

我已经写了一个程序:

CREATE OR REPLACE Table_CHANGES(d IN AB.d%TYPE)
AS
  aaa     AB.a%TYPE;
  aab AB.b%TYPE;
  i             NUMBER   :=   0;
  countRow      NUMBER; 

CURSOR distinctUserIdCursor IS 
    SELECT DISTINCT urt.a, urt.b FROM AA urt WHERE urt.d = aad ORDER BY  urt.a;

BEGIN
    OPEN distinctUserIdCursor;
    LOOP

    FETCH distinctUserIdCursor INTO aaa, aab;
    EXIT WHEN distinctUserIdCursor%NOTFOUND;

    SELECT COUNT(*) INTO countRow FROM AB ur
    WHERE ur.a = aaa 
    AND ur.b = aab
    AND ur.d = aad;

    IF (countRow > 0) THEN
        DBMS_OUTPUT.PUT_LINE('Entry exist in AB');
    ELSE
        INSERT INTO AB 
        SELECT urt.a, urt.b, urt.d, urt.e, 
        urt.f FROM AA urt 
        WHERE urt.a = aaa 
        AND urt.d = aad
        AND urt.b = aab
        AND ROWNUM = 1;

        i := i+1;
    END IF;

    IF (i = 1000) THEN
        COMMIT;
        i := 0;
    END IF;

END LOOP;
COMMIT;
EXCEPTION
    WHEN OTHERS THEN
        dbms_output.put_line('Error in Insertion of new role' 
                || '~~~~' || SQLERRM);
CLOSE distinctUserIdCursor;
END;
/

在 Toad 中以 exec Table_CHANGES('value1')exec Table_CHANGES('value2') 执行此过程时,大约需要 40 分钟并在 toad 中继续执行。很难知道蟾蜍实际上是在执行任务还是在睡觉。

我可以优化这个过程,以减少在表AB中插入几千万条数据的时间吗?

【问题讨论】:

    标签: sql oracle oracle11g oracle-sqldeveloper plsqldeveloper


    【解决方案1】:

    我厌倦了使用集合来实现您正在做的事情。请查看这是否符合您的要求并提高性能。

    create table AA(a number, b number,c number,d number, e number,f number );
    
    create table AB(a number, b number,d number, e number,f number );
    

    程序:

        CREATE OR REPLACE procedure Table_CHANGES(aad IN AB.d%TYPE)
        AS
        --  aaa           AB.a%TYPE;
        --  aab           AB.b%TYPE;
        --  i             NUMBER   :=   0;
        --  countRow      NUMBER; 
    
       ///**Put some filtering logic here like i have put a minus ***///
        CURSOR distinctUserIdCursor(aad number) IS 
            SELECT DISTINCT  urt.a, 
                    urt.b,
                    urt.d, 
                    urt.e, 
                    urt.f 
            FROM AA urt      
            WHERE urt.d = aad
    
            minus
            SELECT DISTINCT ur.a, 
                    ur.b,
                    ur.d, 
                    ur.e, 
                    ur.f 
            FROM AB ur      
            WHERE ur.d = aad;
    
    
        type var_cur is table of distinctUserIdCursor%rowtype;
    
        var var_cur;
    
        BEGIN
            OPEN distinctUserIdCursor(aad);
    
            LOOP
    
            FETCH distinctUserIdCursor bulk collect into var limit 100;       
             EXIT WHEN distinctUserIdCursor%NOTFOUND;
    
             FORALL i IN 1 .. var.count SAVE EXCEPTIONS
              INSERT INTO AB 
              VALUES var(i);              
    
            END LOOP;
    
            CLOSE distinctUserIdCursor;
    
        COMMIT;
    
        EXCEPTION
            WHEN OTHERS THEN
                dbms_output.put_line('Error in Insertion of new role' || '~~~~' || SQLERRM);
              FOR indx IN 1 .. SQL%BULK_EXCEPTIONS.COUNT
                 LOOP
                    DBMS_OUTPUT.put_line (SQL%BULK_EXCEPTIONS (indx).ERROR_INDEX|| ': '
                       || SQL%BULK_EXCEPTIONS (indx).ERROR_CODE);
              END LOOP;
    
        END;
        /
    

    执行:

    execute Table_CHANGES(3)
    

    【讨论】:

      猜你喜欢
      • 2014-11-26
      • 2012-11-11
      • 2011-01-08
      • 2014-07-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-30
      • 1970-01-01
      相关资源
      最近更新 更多