2011-07-20 56 views
3

我想在大約1200萬條記錄的表上運行以下內容。在SQL Server 2008中添加列鎖表鎖定?

ALTER TABLE t1 
ADD c1 int NULL; 
ALTER TABLE t2 
ADD c2 bit NOT NULL 
DEFAULT(0); 

我在分期完成它和時機似乎很好,但我在生產做之前,我想知道在新列的創建(指定一個默認值特別是當對錶鎖定的工作方式)。那麼,有人知道嗎?整個表是否被鎖定,或者在默認值插入過程中行被逐個鎖定?還是做了不同的事情呢?

+0

http://stackoverflow.com/questions/1703597/lock-escalation-whats-happening-here – Jacob

回答

4

是的,它會鎖定表格。

整體而言,表格具有單一架構(一組列和相關類型)。因此,至少爲,將需要架構鎖來更新表的定義。


去想想事情會如何運作反之 - 如果每行被單獨更新,如何將任何並行查詢工作(特別是如果他們參與新列)?


和默認值時INSERT和DDL語句唯一有用的 - 所以,如果你指定一個新的默認10,000,000行,該默認值必須適用於所有這些行。

+0

「默認值僅在INSERT和DDL語句中有用」 - 關於引用操作ON ** UPDATE ** SET DEFAULT並開啓** DELETE ** SET DEFAULT? ;) – onedaywhen

+0

我知道它會在更新表的* definition *的時候鎖定,但是當它更新時每個行的默認值會保持鎖定狀態?更新表格定義非常快,大概2秒鐘。使用默認值更新每一行的地方沒有那麼近,所以這是出現性能問題的地方,如果有的話。 – Eli

+0

如果該列將不爲空,則只需添加一個默認值即可。 – HLGEM

4

是的,它會鎖定。

DDL語句發出一個Schema Lock (see this link)這將阻止訪問表,直到操作完成。

有沒有真正解決這個問題的方法,如果你仔細想想,這是有道理的。 SQL需要知道表中有多少個字段,並且在此操作期間,某些行的字段將比其他字段更多。

另一種方法是用正確的字段創建一個新表,插入,然後重命名錶以將它們交換出來。

0

我還沒有看到添加列時鎖機制是如何工作的,但我幾乎100%肯定行是不可能的。

當你在SQL Server管理器中用拖放操作(我知道你在這裏沒有這樣做,但是這是一個公共論壇)時要注意,因爲有些更改是破壞性的(幸運的是,SQL Server 2008,至少R2,在這裏更安全,因爲它告訴你「不能做」而不是僅僅做它)。

但是,您可以在單個語句中同時運行兩列添加,並減少流失。

8

在SQL Server 11(Denali)之前,添加具有默認值的非空列將在幕後運行更新以填充新的默認值。因此,它將鎖定在1200萬行更新期間的表。在SQL Server 11中,不再是這種情況,該列將在線添加並且不會發生更新,請參閱Online non-NULL with values column add in SQL Server 11

在SQL Server 11和之前的版本中,在表上獲取Sch-M鎖以修改定義(添加新列元數據)。此鎖與任何其他可能的訪問(包括髒讀)不兼容。不同之處在於:在SQL Server 11之前,此鎖將保留用於數據大小操作(更新12M行)。在SQL Server 11中,鎖只能保留一小段時間。在SQL Server 11之前的更新行中,不需要獲取行鎖,因爲表上的Sch-M鎖確保在任何單獨的行上不會發生任何衝突。

+0

雖然我的猜測是Denali現在不會幫助他,但我會爲您提供有關新版本的+1的相關信息。 –

+1

+1 - 從內部人員的角度來看,總是很好 – JNK