Sql server 加载数据时更新语句

Sql server 加载数据时更新语句,sql-server,tsql,Sql Server,Tsql,我有以下场景:我在10M行表上运行update语句,以更新某个状态标志。当语句仍在运行时,新数据已被摄取到表中。问题是:这些新数据会受到更新的影响,还是只考虑最初的10M?update->首先选择要受影响的行,锁定它们以防止任何更改,然后更新这些行 您可以毫无问题地插入新行(如果没有违反约束:) UPDATE语句不会看到在UPDATE之后插入的任何行,因此它们不会被更改。这取决于隔离级别。如果有人使用NOLOCK,新行将可见更新表中的每一行会将锁定升级到表级别,换句话说。。。这比公认的答案说的要

我有以下场景:我在10M行表上运行update语句,以更新某个状态标志。当语句仍在运行时,新数据已被摄取到表中。问题是:这些新数据会受到更新的影响,还是只考虑最初的10M?

update->首先选择要受影响的行,锁定它们以防止任何更改,然后更新这些行

您可以毫无问题地插入新行(如果没有违反约束:)


UPDATE语句不会看到在UPDATE之后插入的任何行,因此它们不会被更改。

这取决于隔离级别。如果有人使用NOLOCK,新行将可见更新表中的每一行会将锁定升级到表级别,换句话说。。。这比公认的答案说的要复杂得多,但我相信我的答案涵盖了OP的目标。当然,关于锁定的文档有10000多个单词。@khidir您会比您想象的更快地遇到这些问题。一旦您意识到更新一个10M表需要花费很长时间并冻结系统,您将尝试使用游标或批处理更新。如果您想使用一个表作为队列,事情会变得复杂得多,简单的锁定就不需要了,这取决于队列的大小。如果您使用NOLOCK或readuncommitted(两个都是坏主意),新记录将可见。你想做什么?您打算如何修改10M行?另一方面,更新表中的每一行会将锁升级到表级别,并防止在进行大规模更新时插入其他行。如果您尝试分批执行更新,那么如果使用读取提交的隔离级别,则批之间的更改将可见。这两个级别均未使用(NOLOCK或读取未提交),因此我猜新记录将不可见。修改只是设置一个列[Status]=1,它不是
而是
,如果该列是
,则更新它可能会锁定整个表-在
字段上创建索引没有意义,因为50%的行将有一个值,另50%的行有另一个值。因此,服务器将执行全表扫描,锁定整个表。这可能会在更新运行期间阻止插入,或者延迟更新直到所有插入完成。无论哪种情况,它都是sloow,可以冻结系统。10M中没有其他行被修改的可能性有多大?您可以使用快照隔离来避免阻塞其他事务。通过快照隔离,服务器保持修改行的原始状态,以便每个事务都能看到启动时的数据,但读卡器不会阻止写入程序,反之亦然。只有当两个事务试图修改同一行时,才会发生阻塞。临时版本存储在tempdb中,因此如果需要修改所有行,那么最终可能会在tempdb中存储10M个临时行。