Sql 从Oracle表中删除

Sql 从Oracle表中删除,sql,oracle,oracle11g,sql-delete,Sql,Oracle,Oracle11g,Sql Delete,我在一个表中有大量的数据,我正在用下面的查询从表中删除数据。但删除大约300-400万行需要2-3个小时。有什么快速删除的方法吗 DELETE /*+parallel (aa 64)*/ from ua_contacthistory_bkp PARTITION (ua_contacthistory_bkp_08JUL2018) aa WHERE aa.CAMPAIGN_CODE='C000000333' 注意,要执行并行DML,必须使用 ALTER SESSION ENABLE PARALL

我在一个表中有大量的数据,我正在用下面的查询从表中删除数据。但删除大约300-400万行需要2-3个小时。有什么快速删除的方法吗

DELETE /*+parallel (aa 64)*/
from ua_contacthistory_bkp PARTITION (ua_contacthistory_bkp_08JUL2018) aa
WHERE aa.CAMPAIGN_CODE='C000000333'

注意,要执行并行DML,必须使用

 ALTER SESSION ENABLE PARALLEL DML;
或者提示
启用\u并行\u DML

根据所使用的并行度,一个好的方法是使用4、8、16等进行测试,以查看
DOP
的增加是否真的可以缩放,即有效地减少
经过的时间

您可能会发现64的
DOP
不是最佳选择,例如,如果遇到光盘系统瓶颈

从技术上讲,您也可以在当前分区下使用基于
CAMPAIGN\u code
的列表子分区模式来实现一个

这可以完全避免使用
delete
而使用
DROP子分区
,或者至少进一步限制
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
谓词选择除包含要删除代码的行之外的所有数据(包括空值)

2) 将新的临时表与分区交换

alter table ua_contacthistory_bkp exchange partition ua_contacthistory_bkp_08JUL2018
with table TMP
including indexes;
现在
TMP
表包含完整的数据(您可以删除它或您喜欢的任何内容)和分区
ua\u contacthistory\u bkp\u 2018年7月8日
除删除的代码外的所有原始数据

如果对分区表进行了索引,则需要格外小心。可以在TMP表和exchange上创建本地索引(请参见包含索引的
)。必须重新生成全局索引


这种方法有积极的副作用,因为您可以压缩表或重新排序数据(在创建
TMP
时使用
ORDER BY
),以优化访问。

我不知道您的表条件和业务逻辑

但我更喜欢添加整数类型,而不是带有 默认值为
1
,在我的表格中命名为
active
,首选
更新
而不是
删除
(要显示隐藏所有行数据,只要需要,就有机会轻松浏览已删除的记录),尤其是对于 数百万行和很多列


更新
插入
相比,
删除
被认为是一项昂贵的操作,尤其是从撤消数据生成操作的角度来看。对于
插入
而言,只需将
ROWID
列插入
Undo
段,但在
删除
时,即使表中有一百列,也将
所有列插入
Undo
段。i、 它们是反向操作。顺便说一句,如果
更新
只是一列(
活动
)是首选,那么撤销段应该与
ROWID
活动
列相关,仅此而已。

只是为了排除明显的问题-删除整个分区-是否删除该分区中的所有内容,或者你还想保留其他活动代码吗?@AlexPoole还有其他活动代码。我想删除一些特定的活动数据