我的应用程序中的报告运行一个需要5到15秒的查询(限制为将返回的行数)。 该查询对我的应用程序的几乎所有主表(客户,销售,单位等)都有8个连接。
一个小工具告诉我,在这个时候,所有这8个表都被锁定了共享表锁。这意味着,此时不会进行更新操作。
来自朋友的一个解决方案是,在查询中进行每次连接,这对于拥有NoLock的100%正确数据(脏读)都不具备任何作用,因此这8个表中只有1个将被完全锁定。 这是一个好的解决方案吗?对于99%的数据来自一个表的报告,解锁较少的prio表?
答案 0 :(得分:4)
NOLOCK
表示根本没有锁定。
您的查询可能会返回截至UPDATE
之前的部分数据,以及单个查询中UPDATE
之后的部分。
就像借记没有信用卡和这些东西一样。
例如,我只是在一个大表上运行此查询:
SELECT SUM(LEN(name))
FROM master WITH (NOLOCK)
OPTION (MAXDOP 1)
---
18874367
所有name
的长度均为1
。
然后我重新开始并在查询中间更新了表格:
UPDATE master
SET name = 'tt'
WHERE id <= 10000
SELECT SUM(LEN(name))
FROM master WITH (NOLOCK)
OPTION (MAXDOP 1)
---
18874944
正如我们所看到的,此查询将577
行视为已更新(长度为2
),其他所有行均未更新(长度为1
)。
SELECT SUM(LEN(name))
FROM master WITH (NOLOCK)
OPTION (MAXDOP 1)
---
18884367
此查询在上一个查询完成后立即运行,查看所有更新。
答案 1 :(得分:4)
尝试查看READ COMMITTED SNAPSHOT而不是NOLOCK。这意味着数据可能“旧”但永远不会变脏。
答案 2 :(得分:0)
没关系,只要你非常强调这句话:
拥有100%正确的数据(脏读)并不具备任何作用
所以你可能不想在你的销售表中添加一个nolock提示,但你的customers表(可能会看到更少的更改)可能没问题。即便如此,您可能不会在单个查询中使用那么多客户记录,但如果确实发生了变化,则可能是一个大问题。因此,您可能希望为该表指定rowlock
提示。