暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle 每天在分区表上删除大量数据,但不按分区键删除

askTom 2017-05-08
721

问题描述

嗨,汤姆,
首先,感谢您为回答每个人的问题所做的巨大努力。

最近,我努力删除我们系统 (OLTP) 中的数据。

我们需要删除的表都是由start_Time分区的 (主要由系统中的每个查询使用)。
问题是特定客户想要使用db_insertion_time列其他搜索属性 (例如event_type) 删除 (并且仅删除) 旧数据。
此外,还有一个选项可以在每个事件记录中保留带有preserve_indication的spefic记录 (假设每天1k)。
还有一件事是DB TZ被配置为UTC。Customer want deletion to be done with Local Time (UTC-2) timings

进入系统的事件率 = 每天1M。
事件保留时间 = 30天。

参与删除的表格:
1。 t_event (按start_time分区)-pk(event_id start_time)global index(event_id)-OGG双向复制所需 (通过event_id)。
2。 t_event_not_partitioned pk(event_id start_time) -较小的表 (t_event的子副本-并非所有列都存在)
系统中不包括start_time的任何可能的搜索的大量索引,包括db_insertion_time索引。

以及事件的大量卫星表 (按开始时间分区)-PK (事件id开始时间XXXX # _id) -。
大多数表每个事件有2-5条记录。
1每个事件有10条记录。
1每个事件有20条记录。

3。事件 _ xxxx1
4。事件 _ xxxx2
5。事件 _ xxxx3
6。事件 _ xxxx4
t。 t_event _。。。
-------------------

在删除过程之前,我们创建了一个result_set,其中包含所有需要删除的事件 (94% 事件在同一个分区中,5% 在昨天的分区中 (UTC问题),很少在其他分区中)

我们的第一个方法是:
1。创建结果集 (id = 1)。
<
插入到t_result_set中从t_events中选择1 rs_id,event_id,start_time,其中db_insertion_Time <。。。。。和 。。。。
/>
2。删除声明例如:
<
从t_event中删除其中 (event_id,start_time) 中的 (选择event_id,start_time从t_result_set中删除其中rs_id = 1);
从t_event_search中删除 (选择event_id,start_time),其中rs_id = 1);
提交;-在这里提交第2节的重试目的
对于sateltile表中的每个表
从t_event_XXXX中删除 (选择event_id,start_time),其中rs_id = 1);
提交;-在这里提交第2节的重试目的
结束循环;
/>
此方法会生成大量的重做/撤消I/O,并花费大量时间。

所以第二个方法是用列row_seq (按start_time排序) 创建结果集
所以这次
1。RS创建为
<
插入到t_result_set中
选择1 rs_id,事件 _id,开始时间,rownum rn
从 (选择事件id,开始时间
来自t_events
其中db_insertion_Time <。。。。。和 。。。。
按开始时间订购)
/>
2。每次使用row_seq列以50k的块进行删除 (与以前一样,在row_seq上进行While循环)。
重做/撤消较小,但仍然有很多I/O。

我还没有测试的第三个方法是使用分区交换。
1。创建结果集
2。在t_events表中查找哪些事件需要停留preserved_events
2。 Delete the t_event_not_partitioned tables by resultset。
3。 For each table in satelite tables copy preserved events to temp table + creating constraints。
5。 Perform partition exchange。
6。 drop new temp table。

This will probably work better but will make us to face with a new problem (global index TX LOCK in the t_event table)。
i read somewhere that maybe we can delete the records for this table, copy the preserved events to temp table。 delete the records in t_events, truncate the partition, reinsert the records - will avoid invalidating the index but will make it not so good for performance)。

Please help me find the best solution。 i know there isn't a magic solution for all tables togehter but the biggest problems are the global index + the tables with a large amount of records(15M)。

你觉得第三种方法怎么样?也许是第四个?

thanks。

专家解答

最终,有3种方法可以在Oracle中转移数据

1) 不要 “真正” 移动它 (即截断,分区交换,丢弃等)
-最少的工作
-db/app设计必须支持预期的操作
-如果您有任何类型的全局索引,那么由于在操作期间或之后需要进行索引维护,这些好处中的大多数都会丢失

2) 通过标准SQL移动它
-简单,但通常有很多撤消/重做

3) 通过优化的SQL (例如,直接模式,nologging,并行dml,延迟索引维护等) 移动它
-更少重做
-通常锁定/并发限制

在我看来,无论你做什么,你都会有某种痛点,因为你的数据库物理设计不支持所请求的操作。同样,如果您负担不起任何类型的锁定,那么您的选择就会变得更加有限。

很抱歉-我没有太多选择-您只需要进行一些基准测试,并尝试在影响与归档速度之间做出最佳折衷。

也许还有一个好问题-为什么需要删除?
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论