当我选择所有WITH(NOLOCK)时,在扩展表上选择了多少行?

时间:2014-05-29 13:31:18

标签: sql sql-server tsql locking

想象一下,我的数据库中有一个foo表,而每隔几毫秒我就是INSERTING这个表的新行。

运行以下查询时:

SELECT *
From foo
WITH(NOLOCK)

随着表格不断扩展,SQL server如何在没有锁定的情况下运行查询时,决定在搜索结果中获取该表的行数?

1 个答案:

答案 0 :(得分:6)

是未指明的行为。 NOLOCK可以返回所有行,根本不返回任何行(是的,它可以!),它可能会遗漏一些行,并且它可以返回重复的行。从字面上看,所有案例都是可能的。实际上,如果表经历了更改(INSERTS),很可能会出现一些缺失的行和一些非常概率很高的重复行。解释与nolock查询扫描数据的方式(allocation order中)以及数据修改如何移动数据(b-tree上的页面拆分,堆上的行向前)有关。这些数据移动可以在当前扫描点之前或之后移动数据,这将导致数据被省略(丢失,当在读取之前移动到当前扫描点之后)或数据被复制时(在移动到当前扫描点之前)它被读了一次,甚至两次。)

有关更详细的讨论,请参阅Previously committed rows might be missed if NOLOCK hint is used