【发布时间】:2019-04-22 00:55:23
【问题描述】:
以下查询通常会返回大量结果(大约 750k 个结果)。但是,在生产中,我遇到了返回 0 结果的零星情况。如果我们在它返回 0 后的下一秒重新运行它,它会正常返回结果。
我确信数据仍然存在并且不应该有任何东西会删除它...
我在几个地方看了看,我找不到可能导致上述问题的原因......而且,似乎没有一种简单的方法来复制它......它只是随机的.
由于我的 SQL 知识非常有限,您能否考虑一下可能发生这种情况的某些场景?或者也许建议简单的调试方法?
SELECT MAX(Table1.Cust_ID) AS cust_id, Table1.Email, MAX(Table1.Cust_Name) as cust_name
FROM dbo.Table1 WITH (NOLOCK)
INNER JOIN dbo.Table2 WITH (NOLOCK)
ON Table1.id = Table2.id
WHERE Table1.some_id = 100 AND Table1.some_value = 'test_value'
AND Table1.some_boolean_1 = 1
AND Table1.some_date_1 IS NULL
AND (Table1.some_boolean_2 IS NULL OR Table1.some_boolean_2 = 1)
AND (Table1.some_date_2 > '20171119' OR Table1.some_date_3 > '20171119' OR
Table2.some_date_3 > '20171119')
GROUP BY Table1.Email
非常感谢!
【问题讨论】:
-
逐行检查所有那些 WHERE 子句并找到记录脱落的地方?每隔几秒查询一次表并确认记录没有被批量删除?
-
这很可能是“按设计工作”。
NOLOCK可以跳过行、重复行和(至少在旧版本中)由于数据移动而出错,尤其是在负载下。如果您需要可靠的结果,请不要使用NOLOCK——坚持使用READ COMMITTED,或者使用快照隔离。NOLOCK仅对正确结果并不重要的查询(例如,监视将立即重新运行的查询)远程有用。 -
是的,
nolock可以跳过行。请参阅dba.stackexchange.com/a/71640/5203 以及那里的链接。 -
NOLOCK对页面结构执行“原始”读取。它不仅在行级别上不一致,而且根本不一致。它绝对可以跳过您感兴趣的所有行,如果它出现在页面拆分的中间。资料来源:来自一个查询的个人经验,该查询使用GROUP BY执行了一堆COUNT(*)s,当服务器负载过重时突然开始报告我的表完全为空(显然,它不是)。这个问题只发生过一次,但它已经足够严重,需要切换到快照隔离。 -
您的查询在语法上不正确 - 可能是由于您的混淆尝试造成的?您不能选择 3 列并仅按其中之一进行分组。
标签: sql sql-server nolock