sql - 从 Oracle 表中删除
问题描述
我在表中有大量数据,我正在使用以下查询从表中删除数据。但是删除大约 3-4 百万行大约需要 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;
或提示ENABLE_PARALLEL_DML
。
根据使用的并行度,一个好的方法是用 4、8、16 等进行测试,看看是否增加了DOP
实际规模,即有效地减少了elapsed time
.
您可能会发现DOP
64 不是最佳选择,例如,如果您遇到磁盘系统瓶颈。
从技术上讲,您还可以使用基于当前分区的 LIST 子分区模式来实现复合分区。CAMPAIGN_CODE
这可以完全避免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 表上创建本地索引,并且交换(请参阅including indexes
)必须重建全局索引。
这种方法具有积极的副作用,因为您可以压缩表或重新排序数据(ORDER BY
在创建时使用TMP
)以优化访问。
推荐阅读
- regex - 有效 SSN 或其他 ID 的正则表达式
- grafana - 选择比给定时间更新的普罗米修斯警报
- scala - Scala:从 dataframe.foreach 访问/编辑地图
- tree - 使用 HyperGraphQL 检索父母和孩子
- rest - 通过 REST api (v2) 将文章发布到公司 LinkedIN 页面
- spring-boot - 当从控制器启动的作业失败时,如何防止弹簧批处理关闭应用程序?
- django - 在 Django 部署期间配置不正确的 urls.py (Django 2.1)
- websocket - Websocket 握手:“Sec-WebSocket-Accept”标头值不正确
- python - Numpy:将列表转换为方形数组
- python - Python中具有不同签名的钻石继承