我想使用主键和外键每6个月从10个相关表中删除旧记录。我计划在单个事务块中执行此操作,因为如果出现任何故障,我必须回滚更改。我的查询会像这样
DELETE FROM PARENT_TABLE WHERE PARENT_ID IN (1, 2, 3,etc);
DELETE FROM CHILD_TABLE1 WHERE PARENT_ID IN (1, 2, 3,etc);
要删除的记录大约为1百万。在单个交易中删除所有这些是否安全?怎么会有这种表现?
修改
更清楚我的问题。我将详细介绍我的执行计划
I am first retreiving primary keys of all the records from the parent table which has to be deleted and store it to a temporary table
START TRANSACITON
DELETE FROM CHILD_ONE WHERE PARENT_ID IN (SELECT * FROM TEMP_ID_TABLE);
DELETE FROM CHILD_TWO WHERE PARENT_ID IN (SELECT * FROM TEMP_ID_TABLE);
DELETE FROM PARENT_TABLE WHERE PARENT_ID IN (SELECT * FROM TEMP_ID_TABLE);
COMMIT;
任何失败的回滚。
鉴于我可以从所有这些表中删除大约一百万条记录,将所有内容放在一个事务块中是否安全?
答案 0 :(得分:2)
首先:创建适当的备份并在开始删除记录之前对其进行测试
您要求的记录数主要取决于数据库服务器的配置(硬件)。您必须对其进行测试,可以在该特定服务器上删除多少条记录而不会出现问题。从例如开始然后1000条记录增加每次迭代的数量,而它似乎太慢了。如果您有复制,则设置和从属性能也会影响行号(过多的写入请求可能会导致复制的严重延迟)。
建议:在开始删除之前,删除所有外键和索引(主键和与用于执行操作的where子句相关的索引除外)。
修改强>
如果要删除的记录数大于不记录的记录数,请考虑将记录复制到新表中,然后重命名旧表和新表。第一步,使用CREATE TABLE .. LIKE
语句复制表的结构,然后删除所有不必要的索引和约束,复制记录,添加索引,然后重命名表。 (如果需要,将原始表中最新的记录复制到副本中),然后删除旧表。
答案 1 :(得分:2)
你可能会成功。但这并不明智。随机的东西(例如,网络故障)可能会导致巨大的交易中止。您可能会长时间阻止其他活动。等
“旧”是否记录了比日期X更旧的所有内容?如果是这样,那么对PARTITIONing
旧行使用DROPping
会更有效 。我们可以讨论细节。糟糕,您有FOREIGN KEYs
,与PARTITIONing
不兼容。所有表都有FK吗?
为什么要在删除前等待6个月?每天6K行将具有相同的效果,并且侵入性和风险更小。
IN ( SELECT ... )
表现糟糕,请改用JOIN
。
如果某些表只是标准化,为什么还要从它们中删除呢?
每笔交易可以删除100个ID吗?这将更安全,更少侵入。
答案 2 :(得分:1)
我认为首先你必须在另一个数据库中移动数据 使用单个事务删除所有10个表格,这个表格可以非常安全地立即回滚,并在用户交互次数非常少时从实时数据库中删除数据more info