我如何优化用于从表中复制数据的 oracle 过程?

How can i optimize an oracle procedure used to copy data from tables?

我的 oracle 数据库中有两个不同的 table。我会只复制我的第一个 table (ANOTHER_TABLE) 的部分数据,只选择一些列并过滤行,到一个新的 (NEW_TABLE).

我尝试了以下过程,使用游标,但我注册了很长的执行时间。 我如何优化此 oracle sql 程序?有可能吗?

有关信息,ANOTHER_TABLE 包含大约 50 万条记录。

PROCEDURE IMPORT_DATA
  AS
  BEGIN
    DECLARE
      c_FIELD1 ANOTHER_TABLE.FIELD1%type;
      c_FIELD2 ANOTHER_TABLE.FIELD2%type;
      row_found NUMBER;
      CURSOR c
      IS
        (
        -- choose only valid data
        SELECT FIELD1, FIELD2
        FROM ANOTHER_TABLE
        WHERE FIELD2 = '1'
        ) ;
    BEGIN
      OPEN c;
      LOOP
        FETCH c INTO c_FIELD1, c_FIELD2;
        EXIT
      WHEN c%notfound;
        BEGIN
          -- verify the record existance to decide if it is 
          -- necessary an update or an insert operation
          SELECT 1
          INTO row_found
          FROM NEW_TABLE
          WHERE FIELD1 = c_FIELD1;
          -- update record
          UPDATE NEW_TABLE
          SET FIELD2 = c_FIELD2
          WHERE FIELD1 = c_FIELD1;
        EXCEPTION
        WHEN NO_DATA_FOUND THEN
          -- insert record
          INSERT
          INTO NEW_TABLE
            (
              FIELD1,
              FIELD2
            )
            VALUES
            (
              c_FIELD1,
              c_FIELD2
            );
        WHEN TOO_MANY_ROWS THEN
          -- duplicated record
          -- show error!
        END;
      END LOOP;
      CLOSE c;
      COMMIT;
    END;

我只会以最快的方式将一个 table 的相同数据复制到另一个。我该如何优化它?

谢谢

一般来说,最快的处理方式是使用单个查询,而不是使用游标。如果你想在 NEW_TABLE 中插入新的、不同的值(如标题所示),那么你可以使用单个 INSERT:

INSERT INTO NEW_TABLE(FIELD1, FIELD2)
    SELECT DISTINCT FIELD1, FIELD2
    FROM ANOTHER_TABLE A
    WHERE FIELD2 = '1' AND
          NOT EXISTS (SELECT 1
                      FROM NEW_TABLE N
                      WHERE A.FIELD1 = N.FIELD1
                     );

您的代码也在更新数据。为此,您可以使用 MERGE 或先删除重复的行:

DELETE FROM NEW_TABLE
    WHERE EXISTS (SELECT 1
                  FROM ANOTHER_TABLE A
                  WHERE A.FIELD1 = N.FIELD1
                 );

然后运行上面的查询。