根据标准从一个非常大的桌子中删除旧记录



i有一个包含3亿记录的表(表A(,我想根据某些标准进行数据保留活动。所以我想删除该表的大约200m记录。

关于性能,我计划创建一个新的表(Table-b(,其中最古老的10m记录来自Table-A。然后,我可以从与标准匹配的表B中选择记录,并将其删除在表A。

从表-A中提取10m记录并使用SQL加载器加载到B加载〜5小时。

我已经创建了索引,并且在适用的情况下使用并行32。

我想知道的是

  • 是否有更好的方法从表A中提取并将其加载到表格中。
  • 除了创建临时表(表格(外,还有什么更好的方法。

DBMS:Oracle 10G,PL/SQL和Shell。

谢谢。

如果要删除表的70%的记录,最好的方法是创建一个包含剩下的30%行的新表格,丢弃旧表并重命名旧桌子名称的新表格。创建新表的一种可能性是创建台式式语句(CTA(,但也有可能使对运行系统的影响较小,例如人们可以使用实体视图选择剩余数据并将实现的VIE转换为表。该方法的详细信息取决于要求。这种阅读和写作效率要高得多,然后删除了旧表的行。

如果删除旧表的行,则可能有必要重新组织旧表,这也将以书写剩余的30%的数据。

通过您的标准分区表可能是一个选项。

考虑标准的案例是本月。整个1月的数据都属于Jan分区。所有2月的数据都属于2月分区...

那么,当删除所有旧的1月数据时,您只需放下分区。

使用rowid最好使用,但内联光标可以帮助您更多插入表A值(从表B中选择 *,其中=标准(然后截断表A

  • 是否有更好的方法从表A中提取并加载它?您可以使用并行CTA-创建table-b作为从表-A中进行选择。您可以在一个步骤中使用压缩和并行查询。

  • table-b。除了创建温度以外,还有更好的方法
    表(表B(?更好的方法是对表A

  • 进行分区

更好的方法是对表A进行分区,但是如果不是,您可以快速而简单:

declare
    i pls_integer :=0 ;
begin
    for r in
    (   -- select what you want to move to second table
        SELECT  
            rowid as rid,
            col1,
            col2,
            col3
        FROM
            table_a t
        WHERE
            t.col < SYSDATE - 30 --- or other criteria 
    )
    loop
        insert /*+ append */ into table_b values (r.col1, r.col2, r.col3 ); -- insert it to second table
        delete from table_a where rowid = r.rid; -- and delete it
        if i < 500 -- check your best commit interval
        then
            i:=i+1;
        else
            commit;
            i:=0;
        end if;    
    end loop;
    commit;
end;

在上面的示例中,您将以小型500行交易移动记录。您可以使用集合和批量插入来优化它,但我想保留简单的代码。

我在搜索条件中使用的列上缺少一个索引。除此之外,引用表上也缺少一些索引。

除此之外, @Miracle173答案也很好,但是如果我们使用该方法,我们也有一些外键可能会造成问题。

1 to @miracle173

最新更新