2009-07-08 57 views
2

我的應用程序中的一個報告運行一個查詢,需要5-15秒(約束爲將返回的行數)。 該查詢有8個連接到我的應用程序(客戶,銷售,單位等)的幾乎所有主表。長查詢中SQL Server表鎖定 - 解決方案:NoLock?

一個小工具顯示了我,在這段時間裏,所有這8個表都被共享的表鎖鎖定。這意味着,此時不會進行更新操作。

來自朋友的解決方案是讓查詢中的每個連接都具有100%正確的數據(髒讀),並且具有NoLock,因此這8個表中只有1個將被完全鎖定。 這是一個很好的解決方案嗎?對於99%的數據來自一張表的報告,解鎖較少的prio表?

回答

4

嘗試查看READ COMMITTED SNAPSHOT而不是NOLOCK。這意味着數據可能會「老」,但永遠不會變髒。

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 

而這個查詢,在前一個完成後運行,看到所有更新。

+0

瞭解我吧?您的意思是,在選擇查詢運行的15秒內,會有一個快速更新,例如,那麼一半的人會有第一個地址,另一半是新的地址? – Kovu 2009-07-08 14:56:06

0

這沒關係,只要你把一個非常非常強調這句話:

這是不mandetory有100%正確的數據(髒讀)

所以你可能不要您不想在銷售表中添加nolock提示,但您的客戶表(可能會看到更少的更改)可能沒問題。即使在那裏,你可能不會在單個查詢中使用這麼多的客戶記錄,但如果有人改變了它,這可能是一個大問題。所以你可能想爲該表指定rowlock提示。