0

我们在 oracle 表中有 2000 万条记录。我们正在尝试将 1400 万条记录传输到另一个模式上的另一个表。

示例:Table1在schema1上有 2000 万条记录,1400 万条记录应该转移到schema2上的Table2中。

我们正在使用光标选择、插入和删除记录。将记录插入table2后,我们将删除table1中的同一组记录。

我们正在使用以下存储过程来实现它:

CREATE OR REPLACE PROCEDURE "SCHEMA1"."ARCHIVE"(FROM_ARCHIVE timestamp, TO_ARCHIVE timestamp,PROCESS_DATE_ARCHIVE timestamp)
AS
    CURSOR C_EXTRACT IS
        SELECT
            COL1,
            COL2,
            COL3,
            .
            .
            .
            .
            COL65
        FROM
            TABLE1
        WHERE 
            UPPER(COL5) ='XXX' AND COL8 >= FROM_ARCHIVE AND COL8 <= TO_ARCHIVE AND UPPER(COL24) NOT IN ('YYY','ZZZ'); 

    FOR C_EXTRACT_REC IN C_EXTRACT
    LOOP
        BEGIN
            INSERT
            INTO
                SCHEMA2.TABLE2
                (
                    COL1,
                    COL2,
                    COL3,
                    .
                    .
                    .
                    .
                    COL65
                )
                VALUES
                (
                    C_EXTRACT_REC.COL1,
                    C_EXTRACT_REC.COL2,
                    C_EXTRACT_REC.COL3,
                    .
                    .
                    .
                    .                   
                    C_EXTRACT_REC.COL65
                );
        END;
    END LOOP;


    FOR C_EXTRACT_REC_DEL IN C_EXTRACT
    LOOP
        BEGIN
            DELETE
            FROM
                TABLE1
            WHERE
                COL1 =C_EXTRACT_REC_DEL.COL1;
        END;
    END LOOP;

EXCEPTION
WHEN OTHERS THEN
    ROLLBACK;
    COMMIT;
END;

选择和删除需要更多时间来执行它。有什么方法可以调整性能,以便选择和删除查询的执行时间更短。

使用这个存储过程,选择、插入和删除 12 条记录需要 12 分钟,选择、插入和删除 1 条 lac 记录需要 30 分钟。

注意:我们正在使用TABLE1中的列表对列进行分区子分区

请帮助我们。

4

2 回答 2

2

您正在使用 2800 万条单独的语句来锤击您的数据库。SQL 是一种集合处理语言。最好在您的过程中使用 2 个语句,如下所示:[未测试]

create or replace procedure schema1.archive
( from_archive timestamp
, to_archive timestamp
, process_date_archive timestamp
)
as
begin
  insert into schema2.table2
  ( col1,
    col2,
    col3,
    .
    .
    .
    .
    col65
  )
  select col1
  ,      col2
  ,      col3
  ,      .
         .
         .
         .
         col65
  from   table1
  where  upper(col5) ='XXX'
  and    col8 >= from_archive
  and    col8 <= to_archive
  and    upper(col24) not in ('YYY','ZZZ')
  ; 
  delete table1
  where  upper(col5) ='XXX'
  and    col8 >= from_archive
  and    col8 <= to_archive
  and    upper(col24) not in ('YYY','ZZZ')
  ;
end;

此过程实现了相同的效果,但速度更快。

问候,
罗布。

于 2013-10-23T05:36:39.600 回答
0

似乎您正在传输大部分数据。如果是这样,请执行以下操作,而不是删除:

create table3 as
  select * from table1
  where  not (upper(col5) ='XXX'
  and         col8 >= from_archive
  and         col8 <= to_archive
  and         upper(col24) not in ('YYY','ZZZ'));

drop table1;
alter table3 rename to table1;
-- Recreate indexes, foreign keys, etc.

还从另一个答案中获取建议,并将插入到 table2 中也成块。

于 2013-10-23T08:09:41.833 回答