i有一个包含3亿记录的表(表A(,我想根据某些标准进行数据保留活动。所以我想删除该表的大约200m记录。
关于性能,我计划创建一个新的表(Table-b(,其中最古老的10m记录来自Table-A。然后,我可以从与标准匹配的表B中选择记录,并将其删除在表A。
中从表-A中提取10m记录并使用SQL加载器加载到B加载〜5小时。
我已经创建了索引,并且在适用的情况下使用并行32。
我想知道的是
- 是否有更好的方法从表A中提取并将其加载到表格中。
- 除了创建临时表(表格(外,还有什么更好的方法。
DBMS:Oracle 10G,PL/SQL和Shell。
谢谢。
如果要删除表的70%的记录,最好的方法是创建一个包含剩下的30%行的新表格,丢弃旧表并重命名旧桌子名称的新表格。创建新表的一种可能性是创建台式式语句(CTA(,但也有可能使对运行系统的影响较小,例如人们可以使用实体视图选择剩余数据并将实现的VIE转换为表。该方法的详细信息取决于要求。这种阅读和写作效率要高得多,然后删除了旧表的行。
如果删除旧表的行,则可能有必要重新组织旧表,这也将以书写剩余的30%的数据。
通过您的标准分区表可能是一个选项。
考虑标准的案例是本月。整个1月的数据都属于Jan分区。所有2月的数据都属于2月分区...
那么,当删除所有旧的1月数据时,您只需放下分区。
使用rowid最好使用,但内联光标可以帮助您更多插入表A值(从表B中选择 *,其中=标准(然后截断表A
-
是否有更好的方法从表A中提取并加载它?您可以使用并行CTA-创建table-b作为从表-A中进行选择。您可以在一个步骤中使用压缩和并行查询。
-
table-b。除了创建温度以外,还有更好的方法
表(表B(?更好的方法是对表A
进行分区
更好的方法是对表A进行分区,但是如果不是,您可以快速而简单:
declare
i pls_integer :=0 ;
begin
for r in
( -- select what you want to move to second table
SELECT
rowid as rid,
col1,
col2,
col3
FROM
table_a t
WHERE
t.col < SYSDATE - 30 --- or other criteria
)
loop
insert /*+ append */ into table_b values (r.col1, r.col2, r.col3 ); -- insert it to second table
delete from table_a where rowid = r.rid; -- and delete it
if i < 500 -- check your best commit interval
then
i:=i+1;
else
commit;
i:=0;
end if;
end loop;
commit;
end;
在上面的示例中,您将以小型500行交易移动记录。您可以使用集合和批量插入来优化它,但我想保留简单的代码。
我在搜索条件中使用的列上缺少一个索引。除此之外,引用表上也缺少一些索引。
除此之外, @Miracle173答案也很好,但是如果我们使用该方法,我们也有一些外键可能会造成问题。
1 to @miracle173