Sql 通过临时表更新

Sql 通过临时表更新,sql,sql-server,Sql,Sql Server,所以我有一个相当大的表(1.5亿行),数据清理查询每晚都会运行。现在这些查询不会更新很多记录,但要获得所需的记录,必须在子查询中多次查询单个表,这需要一些时间 所以,对我来说,执行一个普通的update语句更好吗?或者,如果我将需要的几个结果放在一个临时表中,然后只对这几行执行更新,这将大大减少更新期间的锁,这会更好吗 我不确定update语句锁在大部分时间用于查询时是如何工作的。如果它只更新5条记录,并运行半个小时,它会发布一条在第一分钟更新的记录,还是等到查询结束 谢谢您需要使用(并查看)表

所以我有一个相当大的表(1.5亿行),数据清理查询每晚都会运行。现在这些查询不会更新很多记录,但要获得所需的记录,必须在子查询中多次查询单个表,这需要一些时间

所以,对我来说,执行一个普通的update语句更好吗?或者,如果我将需要的几个结果放在一个临时表中,然后只对这几行执行更新,这将大大减少更新期间的锁,这会更好吗

我不确定update语句锁在大部分时间用于查询时是如何工作的。如果它只更新5条记录,并运行半个小时,它会发布一条在第一分钟更新的记录,还是等到查询结束

谢谢

您需要使用(并查看)表格提示。在批量更新5000行以下数据时,可以将其与update语句一起使用。这将尝试在目标表中放置行锁(如果存在覆盖索引,则在索引键上放置行锁)。如果由于某种原因失败,锁将升级为表锁

(关于锁升级可能发生的原因):

当数据库引擎每1250次检查可能的升级时 新获取的锁,当且仅当 Transact-SQL语句在单个数据库上至少获取了5000个锁 表的引用。当执行Transact-SQL时会触发锁升级 语句在单个引用上至少获取5000个锁 桌子例如,如果语句 在一个索引中获取3000个锁,在另一个索引中获取3000个锁 同一张桌子。类似地,如果 语句在表上有一个自联接,并且每个对表的引用 仅获取表中的3000个锁


实际上,在最后一篇文章中还有更多内容要读。您应该看看混合锁类型升级部分

使用cte怎么样?您可以创建您的cte,然后更新cte,这将反过来更新基表。我一直在重写它们以使用cte,这对性能有很大帮助,但我仍然有一些具有如此多的子系列并与其他大型表绑定,我的CTE版本几乎需要一个小时。没有任何细节,我在这里无法提供多少帮助。但是,任何锁定都不应该太糟糕,因为您可以使用cte将需要更新的行配对。那么,长时间的更新查询是否会等到查询完成后才释放所有锁定?或者,当每个记录都被更新时,它会被释放吗?@Limey:不会,在update语句完成后锁会被释放(因此,当查询完成时)。然后对于少量更新,最好找到记录,将它们放在临时表中,然后使用临时表来运行更新?@Limey:是的,这将是最好的。确保分批运行更新(最多5k)。你可以用一些东西做配料。