sql-server - 从 SQL Server 中的多个表中删除多条记录的最佳实践

标签 sql-server database sql-server-2014 spring-jdbc

拥有一个包含数百万条记录的父表和三个子表,子表的外键指向父表的主键。就像这样:

  Parent
 parent_id (PK) \       Child1
                |     child1_id (PK)
                |---- parent_id (FK)
                |
                |      Child2
                |     child2_id (PK)
                |---- parent_id (FK)
                |
                |      Child3
                |     child3_id (PK)
                |---- parent_id (FK)

父级硬删除数十万条记录的最佳实践是什么?我想在以下条件下删除:DELETE FROM PARENT WHERE [STATUS] = 'DONE'。有没有办法在删除发生时不锁定表?这样其他记录就可以插入到所有这些表中吗? 我能想到的选项:

  1. 在外键上使用CASCADE DELETE
  2. 使用软删除:启动事务,UPDATE Parent SET [DELETED] = 1 WHERE [STATUS] = 'DONE',删除具有这些父 ID 的每个子项,然后硬删除父项和提交。
  3. 与 2. 类似,但使用过程并将要删除的 id 保存在表变量中,这样我就不需要向 Parent 添加新的 [DELETED] 表。
  4. 选择要删除的 IDSELECT Parent_id FROM Parent WHERE [STATUS] = 'DONE',然后通过所有这些 ID 进行批量删除。 (这性能非常糟糕,所以我放弃它)。

我正在使用 SQL Server 2014 和 spring jdbc。

最佳答案

我更喜欢使用 TOP x 批量删除

因此对于每个子表:

DELETE TOP 10000
FROM child1 
FROM child 1 as c1
INNER join parent
On parent_Id = c1.parent_id
AND parent.[STATUS] = 'DONE'

对每个子表重复多个批处理。

您可以定期删除没有子记录的父记录。

DELETE TOP 10000
FROM parent 
FROM parent as p
Left outer join child1 c1
On p.parent_Id = c1.parent_id
AND c1.child_id IS NULL
 Left outer join child2 c2
On p.parent_Id = c2.parent_id
AND c2.child_id IS NULL
Left outer join child3 c3
On p.parent_Id = c3.parent_id
AND c3.child_id IS NULL
WHERE parent.[STATUS] = 'DONE'

每个父级有多少个子级将决定您运行父级删除的频率。你当然可以改变 X 我会测试小,然后增加到 50000

关于sql-server - 从 SQL Server 中的多个表中删除多条记录的最佳实践,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38539908/

相关文章:

将 varchar 值转换为数字数据类型时 SQL 转换失败

sql - 在两次选择中为每对插入记录

sql-server - SQL Server 表简单选择查询花费的时间太长

c# - 在 WPF 应用程序中连接和使用 SQL Compact Edition

sql-server - 基于集合的方法来删除包含点

sql-server - SQL Server 的 'high cpu' 是什么意思

SQL Server - 条件语句的查询执行计划

mysql - Rails 数据库问题 - 错误 1045 (28000) : Access denied for user 'root' @'localhost' (using password: NO)

mysql - 列出所有记录并统计它们在 SQL 中的某个日期范围内使用的次数

tsql - 计算列 - 作为主键