我在一个表中有大量的数据,我正在用下面的查询从表中删除数据。但删除大约300-400万行需要大约2-3个小时。有没有什么快速删除的方法?
DELETE /*+parallel (aa 64)*/
from ua_contacthistory_bkp PARTITION (ua_contacthistory_bkp_08JUL2018) aa
WHERE aa.CAMPAIGN_CODE='C000000333'发布于 2018-07-10 01:57:56
请注意,要执行并行DML,必须使用enable
ALTER SESSION ENABLE PARALLEL DML;或者提示ENABLE_PARALLEL_DML。
根据使用的并行度,一个好的方法是用4,8,16等测试,看看DOP的规模是否真的增加了,即有效地降低了elapsed time。
您可能会发现DOP为64不是最佳选择,例如,如果您遇到磁盘系统瓶颈。
从技术上讲,您还可以在当前分区下使用基于CAMPAIGN_CODE的列表子分区模式实现composite partitioning。
这可以完全避免使用delete,转而使用DROP SUBPARTITION,或者至少进一步限制DELETE语句的范围。
脱机重组
如果您可以让分区短时间脱机(即没有其他会话对其进行修改),这种简单而有效的方法将删除记录,而无需删除。
1)基于您的原始分区创建一个临时表,其中不包括您不想保留的数据。
CREATE TABLE TMP as
SELECT * FROM ua_contacthistory_bkp PARTITION (ua_contacthistory_bkp_08JUL2018) aa
WHERE nvl(aa.CAMPAIGN_CODE,'x') != 'C000000333'WHERE谓词选择除包含要删除的代码的行之外的所有数据(包括NULL)。
2)用您的分区交换新的临时表
alter table ua_contacthistory_bkp exchange partition ua_contacthistory_bkp_08JUL2018
with table TMP
including indexes;现在,TMP表包含了完整的数据(您可以删除它或您喜欢的任何东西),分区ua_contacthistory_bkp_08JUL2018除了删除的代码之外的所有原始数据。
如果对分区表进行了索引,则需要格外小心。可以在TMP表上创建本地索引,还必须重新构建exchange全局索引(请参见including indexes)。
这种方法有积极的副作用,因为您可以压缩表或重新排序数据(在创建TMP时使用ORDER BY )来优化访问。
发布于 2018-07-10 02:09:05
我不知道你的表的条件和业务逻辑,
但我更喜欢添加一个整数类型,非空列,默认值为
1,命名为active到我的表中,并且更喜欢updating它而不是deleting(为了显示或hide所有的行数据,有机会在需要的时候轻松地浏览一下删除的记录),特别是对于拥有数百万行和大量列的表。
与Updating和Inserting相比,Deleting被认为是一个代价高昂的操作,特别是从撤消数据生产操作的角度来看。对于Inserting,您只需要将ROWID列插入到Undo段中,但是当您使用Deleting时,即使表中有100列,您也会将所有列都Inserting到Undo段中。也就是说,它们是反向操作。顺便说一下,如果Updating just a column(active)是首选的,那么Undo段应该关注ROWID和active列,仅此而已。
https://stackoverflow.com/questions/51249625
复制相似问题