Sql 内联的;坦率地说,拥有一个没有足够撤消空间的VLDB(一亿行表计数,即使在PB和zettabytes的今天也是如此)是愚蠢的

Sql 内联的;坦率地说,拥有一个没有足够撤消空间的VLDB(一亿行表计数,即使在PB和zettabytes的今天也是如此)是愚蠢的,sql,oracle,subquery,Sql,Oracle,Subquery,但是,如果您不想在数据中心使用mintotaur,您所能做的就是更改代码。这里有一个选择。鉴于此 select id from tableB where tableB.column1='somevalue' and tableB.date between date1 and date2 。。。返回一百万行,因此尝试从表a中删除太多行,您可以尝试返回较少行的子查询。出于练习的目的,我假设date1到date2指定的范围为30天:您需要相应地调整以下代码 for i in 1..10 l

但是,如果您不想在数据中心使用mintotaur,您所能做的就是更改代码。这里有一个选择。鉴于此

select id 
from tableB 
where  tableB.column1='somevalue' 
and tableB.date between date1 and date2 
。。。返回一百万行,因此尝试从
表a
中删除太多行,您可以尝试返回较少行的子查询。出于练习的目的,我假设
date1
date2
指定的范围为30天:您需要相应地调整以下代码

for i in 1..10 loop
    delete from tableA 
     where tableA.fk in (select id 
                         from tableB 
                         where tableB.column1='somevalue' 
                         and tableB.date between date1 + (3 * (i-1)) and  date1 + (3 * i)
       ;
    commit;
end loop


这将简单地将select分成十个三天的块。这样做需要更长的时间,但不应破坏撤消表空间。

您可以使用所需的数据(即与选择相反的数据)创建一个新表,删除旧表,最后重命名新表。您可以每天删除行吗,与其使用日期范围,不如使用join而不是子查询,这样会更快…问题是您试图删除大量行,这本身就很慢(尤其是索引),填充回滚段不是性能问题,这与交易中涉及的数据量有关。您可以使用所需的数据(即与选择相反的数据)创建一个新表,删除旧表,最后重命名新表。您可以每天删除行吗,与其使用日期范围,不如使用join而不是子查询更快…问题是您试图删除大量行,这本身就很慢(尤其是索引)。填充回滚段不是性能问题,它与事务中涉及的数据量有关。我无法删除表。它总是在使用中。@user710818我已经在回答中回答了您的评论。如果删除1/10的数据填充了回滚段,那么将9/10的数据插入另一个表肯定也会填充它。@Richardz您知道物化视图是如何工作的吗?如果您提供的
nologging
参数是一个模拟点。“我想我会在我的回答中更清楚地说明这一点。”呜呜,你直到现在才提到不记录,但你所说的不是真的。NOLOGGING会影响重做日志,和撤消段(或回滚段)关系不大。我不能删除表。它总是在使用中。@user710818我已经在回答中回答了您的评论。如果删除1/10的数据填充了回滚段,那么将9/10的数据插入另一个表肯定也会填充它。@Richardz您知道物化视图是如何工作的吗?如果您提供的
nologging
参数是一个模拟点。“我想我会在我的回答中更清楚地说明这一点。”呜呜,你直到现在才提到不记录,但你所说的不是真的。NOLOGGING会影响重做日志,与撤消段(或回滚段)几乎没有关系。这是非常低效的。通过更改子选择可以提高效率,但如果问题是它填充回滚段,则必须在较小的事务中完成(而不是像您建议的那样大一个事务,我没有降级)把它分割开来并不能节省任何时间。同样的工作量最终被完成,这就是为什么我否决了你的答案。你可能还没有阅读完整的问题:“回滚段的大小有问题。我不能增加段的大小。”这不是性能问题。我刚刚提出了分批进行的想法,这将解决问题。即使这仅仅是部分的大小,您仍然建议了一个不正确的解决问题的方法。我的猜测是OP会回来说“这太慢了,为什么”这是非常低效的。通过更改subselect可以提高效率,但如果问题是它正在填充回滚部分,那么它必须在较小的事务中完成(而不是像你建议的那样大一个事务,我没有降级)把它分割开来并不能节省任何时间。同样的工作量最终被完成,这就是为什么我否决了你的答案。你可能还没有阅读完整的问题:“回滚段的大小有问题。我不能增加段的大小。”这不是性能问题。我刚刚提出了分批进行的想法,这将解决问题。即使这仅仅是部分的大小,您仍然建议了一个不正确的解决问题的方法。我猜测OP会回来说“这太慢了,为什么?”
create table foo_bar  
as select  *  
from tableA   
where tableA.fk not in (select id from tableB where 
 tableB.column1='somevalue' and tableB.date between date1 and date2);  
truncate tableA  
drop tableA
alter table foo_bar  rename to tableA
 delete from tableA where tableA.fk in (
    select id from (
            select id from tableB where 
                tableB.column1='somevalue' and tableB.date between date1 and date2 and id in (select distinct fk from tableA.fk)

        )
        where rownum < XXXX 
    )
select id 
from tableB 
where  tableB.column1='somevalue' 
and tableB.date between date1 and date2 
for i in 1..10 loop
    delete from tableA 
     where tableA.fk in (select id 
                         from tableB 
                         where tableB.column1='somevalue' 
                         and tableB.date between date1 + (3 * (i-1)) and  date1 + (3 * i)
       ;
    commit;
end loop