SQL Server表锁定长查询 - 解决方案:NoLock?

时间:2009-07-08 14:44:35

标签: sql sql-server

我的应用程序中的报告运行一个需要5到15秒的查询(限制为将返回的行数)。 该查询对我的应用程序的几乎所有主表(客户,销售,单位等)都有8个连接。

一个小工具告诉我,在这个时候,所有这8个表都被锁定了共享表锁。这意味着,此时不会进行更新操作。

来自朋友的一个解决方案是,在查询中进行每次连接,这对于拥有NoLock的100%正确数据(脏读)都不具备任何作用,因此这8个表中只有1个将被完全锁定。 这是一个好的解决方案吗?对于99%的数据来自一个表的报告,解锁较少的prio表?

3 个答案:

答案 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提示。