Oracle如何从表中删除少数分区数据

标签 oracle partition

我有一个大表,其中有很多数据划分为多个分区。我想保留一些分区,但删除表中的其余数据。我尝试搜索类似的问题,但在 stackoverflow 中找不到。在 Oracle 中编写查询以实现相同目的的最佳方法是什么?

最佳答案

从特定分区中删除数据很容易:此语句清除了 2012 年 2 月的所有数据:

delete from t23 partition (feb2012);

一个更快的方法是截断分区:
alter table t23 truncate partition feb2012;

这里有两个潜在的障碍:
  • 如果我们有引用表的外键,Oracle 不会让我们截断分区。
  • 该操作使任何分区索引无效,因此我们需要在之后重建它们。

  • 此外,它是 DDL,所以没有回滚。

    如果我们再也不想存储该月的数据,我们可以删除分区:
    alter table t23 drop partition feb2012;
    

    当我们想要切换多个分区并且我们不喜欢所有类型的输入时,问题就出现了。我们不能参数化分区名称,因为它是一个对象名称而不是一个变量(没有引号)。所以只留下动态SQL。

    由于您想删除大部分数据但保留分区结构,因此截断分区是最佳选择。请记住使任何完整性约束无效(并在之后恢复它们)。
    declare
        stmt varchar2(32767);
    begin
        for lrec in ( select partition_name
                      from user_tab_partitions
                      where table_name = 'T23'
                      and partition_name like '%2012'
                    )
        loop
            stmt := 'alter table t23 truncate partition '
                        || lrec.partition_name
                      ;
            dbms_output.put_line(stmt);
            execute immediate stmt;
        end loop;
    end;
    /
    

    你绝对应该先用 execute immediate 运行循环调用注释掉了,所以你可以看到你的 WHERE 子句正在选择哪些分区。显然,您有备份并且可以恢复您不想删除的数据。但是进行恢复的最快方法是不需要恢复。

    然后运行此查询以查看您应该重建哪些分区:
    select ip.index_name, ip.partition_name, ip.status 
    from user_indexes i
         join user_ind_partitions ip
          on  ip.index_name = i.index_name
    where i.table_name = 'T23'
    and ip.status = 'UNUSABLE';
    

    您可以以类似的方式自动执行重建语句。

    " I am thinking of copying the data of partitions I need into a temp table and truncate the original table and copy back the data from temp table to original table. "



    那是另一种做事方式。使用交换分区可能会很快。它也可能更慢。它还取决于诸如外键和索引之类的东西,以及已删除分区与保留分区的比率。如果性能很重要和/或您需要定期进行此操作,那么您应该对各种选项进行基准测试,看看哪种最适合您。

    关于Oracle如何从表中删除少数分区数据,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26728011/

    相关文章:

    .net - OracleConnections 会超时吗?如果不是,为什么我的 Oracle session (在 v$session 中)消失了?

    Oracle 作业调度程序不工作

    mysql - 收到错误 1503 : A primary key must include all columns in the table's partitioning function

    java - 为什么 While (rs.next()) 语句在第一次迭代后结束?

    c# - ASP.NET MVC 4 具有一个域模型用于多个应用程序和缓存

    java - 如何在jdbc中检索record%type表?

    testing - Im textbox From 1 to 1000 write testcase to allow only multiple of 5 使用等效分区和边界值分析?

    java - 使用spring data JPA时添加PARTITION语句进行查询

    mysql - 在不改变记录顺序的情况下找到 MIN 和 MAX 的组记录。间隙和孤岛?