从Oracle中删除指定行的最佳方式

从Oracle中删除指定行的最佳方式,第1张

概述我有一个项目,需要偶尔删除几个不同大小的六个表中的几十万行,但它们之间有大约3000万行.由于我已经给出了数据的结构,我不知道六个表中哪一个有哪些行需要被删除,所以我必须对所有的表运行所有的删除.我已经建立了一个针对ID列的INDEX来尝试加快速度,但如果这样可以加快速度,那么它可以被删除. 我的问题是,我似乎找不到一个有效的方式来实际执行删除.为了我的测试目的,我正在运行7384行删除单个测试表 我有一个项目,需要偶尔删除几个不同大小的六个表中的几十万行,但它们之间有大约3000万行.由于我已经给出了数据的结构,我不知道六个表中哪一个有哪些行需要被删除,所以我必须对所有的表运行所有的删除.我已经建立了一个针对ID列的INDEX来尝试加快速度,但如果这样可以加快速度,那么它可以被删除.

我的问题是,我似乎找不到一个有效的方式来实际执行删除.为了我的测试目的,我正在运行7384行删除单个测试表,该测试表有大约9400行.我在Oracle sql Developer中测试了许多可能的查询解决方案:

7384个独立的DELETE语句花了203秒:

delete from table1 where ID=1000001356443294;delete from table1 where ID=1000001356443296;etc...

7384个单独的SELECT语句花了57秒:

select ID from table1 where ID=1000001356443294select ID from table1 where ID=1000001356443296etc...

7384从(SELECT)语句中分离DELETE需要214秒:

delete from (select ID from table1 where ID=1000001356443294);delete from (select ID from table1 where ID=1000001356443296);etc...

1 SELECT语句中有7384个OR子句在哪里拿了127.4s:

select ID from table1 where ID=1000001356443294 or ID = 1000001356443296 or ...

1 DELETE from(SELECT)语句中有7384个OR子句在哪里花了74.4s:

delete from (select ID from table1 where ID=1000001356443294 or ID = 1000001356443296 or ...)

虽然最后一个可能是最快的,但进一步的测试仍然非常缓慢,从9000行表到甚至只有一个20万行表(仍然是最终的表集大小的1%),同样的语句需要14分钟跑步.而>每行更快50%,当对完整的数据集运行时,它仍然推断出大约一天.我有一个很好的权威,我们用来做这个任务的软件可以在大约20分钟内完成.

所以我的问题是:

Is there a better way to delete? Should I use a round of SELECT statements (i.e.,like the second test) to discover which table any given row is in and then shoot off delete querIEs? Even that looks quite slow but… Is there anything else I can do to speed the deletes up? I don’t have DBA-level access or kNowledge.
在我的问题得到回答之前,这是我如何去做的:

尽量减少发表的数量和相关工作.

所有情况都假设您有一个表(PURGE_IDS)从table_1,table_2等中删除.

考虑使用CREATE table AS SELECT进行大量删除

如果没有并发活动,而您正在删除一个或多个表中的30%的行,请勿删除;执行创建表作为选择与您希望保留的行,并交换旧表格为旧表. INSERT / * APPEND * / …如果您负担得起,NolOGGING是非常便宜的.即使您有一些并发活动,也可以使用在线表重新定义来重建表格.

不要运行DELETE语句,你知道不会删除任何行

如果在六个表格中的最多一个中存在ID值,那么请记住您删除了哪些ID,而不要尝试从任何其他表格中删除这些ID.

CREATE table table1_PURGE NolOGGINGAS SELECT ID FROM PURGE_IDS INNER JOIN table_1 ON PURGE_IDS.ID = table_1.ID;DELETE FROM table1 WHERE ID IN (SELECT ID FROM table1_PURGE);DELETE FROM PURGE_IDS WHERE ID IN (SELECT ID FROM table1_PURGE);DROP table table1_PURGE;

并重复.

管理并发如果你必须

另一种方法是使用PL / sql循环遍历表,发出rowcount限制的delete语句.如果针对正在运行删除的表有重大的插入/更新/删除并发负载,则这很可能是适用的.

declare  l_sql varchar2(4000);begin  for i in (select table_name from all_tables              where table_name in ('table_1','table_2',...)             order by table_name);  loop    l_sql := 'delete from ' || i.table_name ||              ' where ID in (select ID from purge_IDs) ' ||              '   and rownum <= 1000000';    loop      commit;      execute immediate l_sql;      exit when sql%rowcount <> 1000000;  -- if we delete less than 1,000,000    end loop;                             -- no more rows need to be deleted!  end loop;  commit;end;
总结

以上是内存溢出为你收集整理的从Oracle中删除指定行的最佳方式全部内容,希望文章能够帮你解决从Oracle中删除指定行的最佳方式所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1167467.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-01
下一篇 2022-06-01

发表评论

登录后才能评论

评论列表(0条)

保存