2009-04-16 57 views
1

我想將整數列添加到具有大量行和許多索引(其數據倉庫事實表)的表中。在SQL Server中高效地添加列

爲了儘可能縮小行寬,此表中的所有列都被定義爲非空。所以我希望新列不爲null,默認爲零。

根據經驗,添加此列需要一些時間,大概是因爲數據庫將需要用填充值的新列重寫所有行。這大概會涉及更新聚集索引和所有非聚集索引。

所以我應該在添加列之前刪除所有索引,然後重新創建它們。 還是有更簡單的方法來做到這一點?

另外我不明白爲什麼添加一個可爲空的列是如此之快。爲什麼這不涉及用每行翻轉的額外空位來重寫記錄。

+0

「爲了儘可能縮小行寬,此表中的所有列都被定義爲非空」 - 這是如何工作的? – 2009-04-16 15:17:58

回答

0

SQL Server是一個面向行的數據庫。這與列式數據庫相反。這意味着在SQL Server中,給定行的所有數據都一起存儲在磁盤上。舉個例子:

假設你有一個包含3列,FirstName,MiddleInitial和LastName的Customer表。然後,假設您在此表中有3條記錄,分別是Jabba T. Hutt,Dennis T. Menace和George W. Bush。

在一排導向數據庫(如SQL Server),記錄將被存儲在磁盤上,例如:

賈巴,T,赫特;丹尼斯,T,威脅;喬治,W,布什;

相比之下,面向列的數據庫將在磁盤上存儲的記錄是這樣的:

賈巴,丹尼斯,喬治; T,T,W;胡特威脅,布什;

其中列被分組在一起而不是行。

現在,當您將行添加到面向行的數據庫(例如SQL Server)中的表中時,每列的新數據必須與現有行一起插入,從而需要大量行的讀/寫操作。因此,如果要爲客戶前綴插入一個默認爲'Mr'的新列,您將得到以下結果:

Mr,Jabba,T,Hutt;丹尼斯先生,威納斯先生;喬治先生,布什先生,

正如你所看到的,所有的原始數據已經被轉移到右邊。另一方面,當插入默認爲NULL的新列時,不必將新數據放入現有行中。因此,移動較少,需要較少的磁盤讀/寫操作。

當然,這是對磁盤上實際進行的過分簡化。處理索引,頁面等時還需要考慮其他事情,但它應該可以幫助您獲得圖片。

澄清我根本不建議你轉到列式數據庫,我只是把那些信息放在那裏,以幫助解釋面向行的含義。

4

這將需要更新聚簇索引,是的 - 畢竟這是表數據。

但我不明白爲什麼任何非聚集索引將不得不更新 - 你的新列不會是任何非聚集索引的成員。

此外,我不知道在這種情況下如何刪除和重新創建索引將有利於您。如果您從另一個表或數據庫批量加載數百萬行數據 - 是的,那麼它可能會更快(因爲INSERT更快) - 但添加列並不真正受到任何索引或約束的影響,我不認爲。

馬克

+1

「但我不明白爲什麼任何非聚集索引都必須更新」 - 添加非空列需要刪除和重新創建表,因此副產品必須刪除並重新創建以及。 – 2009-04-16 18:45:48

0

「此外,我真的不明白,爲什麼添加一列,爲空這麼快很多。爲什麼會出現這種不涉及重新writng一個額外的記錄爲空位翻轉爲每一行。 「

添加可空列只會改變表的定義。個人記錄不受影響。