[英]Table Partitioning to avoid locks
TLDR ; 我正在尝试对表进行分区,以便可以在不锁定其他分区的情况下对每个分区进行操作,但它不起作用。
背景:我正在创建一个数据管道流程,将数据从中央企业数据库导出到 SQL 服务器数据库,可用于分析。 我每天都需要导出完整的表(目前删除旧表,稍后归档),它可以接近 10GB。
为了让它足够快以供使用,我根据“计划”列将表格分成 15 个块。 这是在数据管道中完成的,因此“计划”列中的 15 个可能值中的每一个都被独立处理; 从企业数据库中提取每个计划块,然后在 SQL 服务器表中删除该块的旧数据并上传新数据。
问题是,在 15 个块中执行此操作意味着所有进程相互阻塞。 一切都必须等待其他一切,最终使所有 go 非常慢,并且经常由于超时而失败。
为了解决这个问题,我已经:
根据这里的答案,这应该允许我“一次性删除或添加大量数据”。
但这似乎没有帮助; 我仍然得到块。
所以两个问题:
替代方案我还考虑将目标表分成 15 个表,并尝试将它们与视图重新组合。 那会更好吗? 更差?
过去我遇到过类似的问题,并发工作人员在单个物理分区和不同分区中处理行,但仍然相互阻塞。
发生这种情况的一个原因是,如果其中一名工作人员设法将他们的锁升级到表级别。 您需要在阻塞期间检查等待任务,看看这是否适用于您。
SQL 服务器确实支持将锁升级到分区级别,但这不是默认设置(因为在某些情况下可能会导致更大的死锁概率)。
要启用此选项,您需要设置LOCK_ESCALATION = AUTO
。
如果您正在做的工作是替换分区中的所有行,那么您应该考虑Charlieface 的评论并在每个分区的新空表中执行此操作,并使用TRUNCATE TABLE... WITH (PARTITIONS ())
或ALTER TABLE... SWITCH
清除旧数据和ALTER TABLE... SWITCH
引入新数据(通常都应该是非常快速的操作)。 这意味着插入是真正独立的,并且这种模式可能更有益 w.r.t。 插入的最小日志记录。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.