Eri*_*ard 23 database sql-server scalability sharding
这是我试图解决的问题:我最近完成了数据层重新设计,允许我跨多个分片对数据库进行负载平衡.为了保持碎片平衡,我需要能够将数据从一个碎片迁移到另一个碎片,这涉及从碎片A复制到碎片B,然后从碎片A中删除记录.但是我有几个非常大的表,并且有许多外键指向它们,因此从表中删除单个记录可能需要一秒以上.
在某些情况下,我需要从表中删除数百万条记录,实际上只需要很长时间.
禁用外键不是一种选择.删除大批量的行也不是一种选择,因为这是一个生产应用程序,而大型删除会锁定太多资源,从而导致失败.我正在使用Sql Server,而且我知道分区表,但是对分区的限制(以及企业版的许可费用)是如此不切实际,以至于它们是不可能的.
当我开始研究这个问题时,我认为困难的部分是编写算法,该算法计算出如何从叶级别删除行到数据模型的顶部,以便在此过程中不会违反外键约束.但解决这个问题对我没有好处,因为删除需要在一夜之间消失的记录需要数周时间.
我已经建立了一种将数据标记为虚拟删除的方法,因此就应用程序而言,数据已经消失,但由于其庞大的大小,我仍在处理大型数据文件,大型备份和较慢的查询.表格.
有任何想法吗?我已经在这里阅读了较旧的相关帖子,但没有发现任何有用的信息.
Mit*_*eat 27
请参阅:优化SQL Server上的删除
可能会对此MS支持文章感兴趣:如何解决由SQL Server中的锁升级引起的阻塞问题:
将大批量操作分解为几个较小的操作.例如,假设您运行以下查询以从审计表中删除数十万条旧记录,然后您发现它导致阻止其他用户的锁升级:
Run Code Online (Sandbox Code Playgroud)DELETE FROM LogMessages WHERE LogDate < '2/1/2002'
通过一次删除这些记录几百个,您可以显着减少每个事务累积的锁定数量并防止锁定升级.例如:
Run Code Online (Sandbox Code Playgroud)SET ROWCOUNT 500 delete_more: DELETE FROM LogMessages WHERE LogDate < '2/1/2002' IF @@ROWCOUNT > 0 GOTO delete_more SET ROWCOUNT 0
通过使查询尽可能高效来减少查询的锁定占用空间.大扫描或大量书签查询可能会增加锁定升级的可能性; 此外,它增加了死锁的可能性,并且通常会对并发性和性能产生负面影响.
foo*_*ode 17
delete_more:
DELETE TOP(500) FROM LogMessages WHERE LogDate < '2/1/2002'
IF @@ROWCOUNT > 0 GOTO delete_more
Run Code Online (Sandbox Code Playgroud)
您可以使用SET ROWCOUNT
Mitch建议的相同结果,但根据MSDN,它将不支持DELETE
SQL Server的未来版本中的其他操作:
在将来的SQL Server发行版中,使用SET ROWCOUNT不会影响DELETE,INSERT和UPDATE语句.避免在新的开发工作中使用SET ROWCOUNT和DELETE,INSERT和UPDATE语句,并计划修改当前使用它的应用程序.对于类似的行为,请使用TOP语法.有关更多信息,请参阅TOP(Transact-SQL).