【问题标题】:Selecting and deleting takes more time in oracle stored procedure - Perfornamce tuningoracle存储过程中选择删除需要更多时间-性能调优
【发布时间】:2013-10-23 05:00:13
【问题描述】:

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

示例:Table1schema1 上有 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 中使用列表分区列和子分区列。

请帮助我们。

【问题讨论】:

  • 我看到您使用了 EXCEPTION WHEN OTHERS 来隐藏任何错误,这样如果发生错误,您将不知道它是什么。这似乎无济于事。
  • 另外,您在哪些列上进行分区?这是一个频繁的操作吗,因为分区可以提高效率。
  • @DavidAldridge 我们正在使用 TABLE1 中的列表对 COL22 进行分区和对 COL24 进行子分区。我们每个月都进行分区,即 2011 年 1 月、2011 年 2 月、.......、2013 年 12 月。是否可以删除 JAN2011 的分区并在执行存储过程以删除 JAN2011 一周的数据后,是否可以重新创建 JAN2011 的分区。
  • 您熟悉分区交换吗?看看你是否可以使用它。
  • 不,我不熟悉分区交换。

标签: oracle stored-procedures oracle11g database-performance


【解决方案1】:

您正在使用 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;

此过程实现相同,但速度更快。

问候,
抢。

【讨论】:

  • 我们已经尝试过了,但是执行删除查询需要更多时间。
  • 不可能。一个使用全表扫描的删除语句总是会击败 14M 的单行删除语句。表上有数据库触发器吗?
  • 我们在 table1 中有许多索引、外键约束以及分区和子分区。对于删除零记录,其执行时间为 24 分钟。
  • 如果可能,您可以在执行此过程之前删除索引,然后重新创建它们。
  • 我们处境尴尬。总共有 21 个索引,我们使索引不可用,我们执行了删除语句,然后我们重建了它。重建所有 21 个索引需要 84 分钟。每个索引需要 4 分钟。所以如果我们将存储过程运行一天,那就更耗时了。
【解决方案2】:

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

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。

【讨论】:

    猜你喜欢
    • 2018-12-20
    • 1970-01-01
    • 2020-10-02
    • 2019-03-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-10
    • 2013-07-15
    相关资源
    最近更新 更多