Sql 从大型表中删除记录

Sql 从大型表中删除记录,sql,oracle,oracle11g,database-administration,Sql,Oracle,Oracle11g,Database Administration,我的应用程序中有一个表,它存储pid主键和inst id等数据,其中保存历史数据,最新inst id的行具有最新数据 样本数据如下: 例如:tablename是TESTTABLE pid编号,instit编号,datacol1 varchar2100,datacol2 date pid instid datacol1 datacol2 --------------------------------------- 1 18 sample1 2

我的应用程序中有一个表,它存储pid主键和inst id等数据,其中保存历史数据,最新inst id的行具有最新数据

样本数据如下:

例如:tablename是TESTTABLE pid编号,instit编号,datacol1 varchar2100,datacol2 date

pid instid datacol1 datacol2
--------------------------------------- 1 18 sample1 2/05/2012
1 17 sample2 2/04/2013
1 16 sample2 2/04/2013
2 15 sample3 1/04/2012
2 14 sample3 2/04/2012
在上述结果中,pid 1 id的最新记录为18,pid 2的最新记录为15。 现在,该表已经增加了数十亿条记录,而且大小在1 TB左右太大了 ,计划清除历史数据,保留最新pid,插入组合并删除其余部分


考虑到表的巨大规模,有人能告诉我删除行的更好方法吗?

我的建议是一个多阶段操作,包括1创建一个提取脚本/proc来构建一个新表,只保存所需的行。这将提出一个问题,即最近需要进行多少次修订,这是一个必须回答的问题。将其设计为将输出放入新表中。用户编写、测试并批准后,选择一个时间暂停新活动,运行sql程序创建新表。将整个旧表归档到允许您有选择地恢复的介质中。截断原始表,并使用步骤1提取中的内容重新加载它。测试,测试,测试,并让用户买断每一步。

由于您需要几十亿条记录并计划清除历史数据,我建议您应该选择表分区,可能是按周或按月分区,那么您可以轻松删除旧分区


是的,这需要一些设计上的改变,但这是值得做的,这对应用程序有好处,对长期运行也有好处。

如果您只想保留最新的代码,这段代码可能会很有用

WITH C AS(
    SELECT  ROW_NUMBER() OVER(PARTITION BY pid ORDER BY pid DESC) AS Rn
            ,pid
            ,instid
            ,datacol1
            ,datacol2
    FROM TESTTABLE
)
DELETE FROM C
WHERE Rn != 1

SELECT * FROM TESTTABLE

对将数据存储在分区和删除分区中。希望如此大的表就是这样组织的。从数十亿条记录的表中删除记录总是个问题。您必须实现分区表,然后删除旧分区。sql stm删除将具有高cpu和磁盘i/o;分区表将为您的应用程序性能带来很大好处。感谢您回答@jsbaltes。这种方法已经在UAT中进行了测试,并得到了用户的认可。但是,由于Prod中的数据量很大,因此不确定是否必须以批处理或任何其他方法来完成。因此,从表中删除数据不应超过一天。如果您还没有SQL,我认为这样做可以:从Select pid中选择t1.pid、t1.INSTAD、t2.datacol1、t2.DATACOL2,通过Pid T1从TESTDATA组导入MaxInstitd内部连接T2上的TESTDATA T2。Pid=T1.Pid和T2.Institd=T1.Institd顺序通过T1.Pid,T1.Institd如果保留的数据量相对较小,为30%或更少,则我建议使用它转到一个新表,然后进行双重重命名,使旧表采用类似TESTDATE_BKP的名称,新表成为TESTDATA。然后将索引、约束等重新添加到新表中。您的停机时间将缩短,您的恢复文件将在需要时随时可用。然后在一段安全期后,备份并删除原始表。删除事务将淹没Txn日志…因此我不建议使用该路由。