想象一下,我的数据库中有一个foo
表,而每隔几毫秒我就是INSERTING
这个表的新行。
运行以下查询时:
SELECT *
From foo
WITH(NOLOCK)
随着表格不断扩展,SQL server
如何在没有锁定的情况下运行查询时,决定在搜索结果中获取该表的行数?
答案 0 :(得分:6)
是未指明的行为。 NOLOCK可以返回所有行,根本不返回任何行(是的,它可以!),它可能会遗漏一些行,并且它可以返回重复的行。从字面上看,所有案例都是可能的。实际上,如果表经历了更改(INSERTS),很可能会出现一些缺失的行和一些非常概率很高的重复行。解释与nolock查询扫描数据的方式(allocation order中)以及数据修改如何移动数据(b-tree上的页面拆分,堆上的行向前)有关。这些数据移动可以在当前扫描点之前或之后移动数据,这将导致数据被省略(丢失,当在读取之前移动到当前扫描点之后)或数据被复制时(在移动到当前扫描点之前)它被读了一次,甚至两次。)
有关更详细的讨论,请参阅Previously committed rows might be missed if NOLOCK hint is used。