2010-07-19 51 views
2

我想向已包含數十億行的表添加新列。新列是從現有列導出的。將新列添加到具有數十億行的列數據庫

例如,

new_col1 = old_col1 + old_col2 
new_col2 = old_col1/old_col2 

我試圖做到這一點在下面的方式 - 由一個從表

添加新列

ALTER TABLE table_name 
ADD ( column_1 column-definition, 
column_2 column-definition, 
... 
column_n column_definition) 

讀行之一,填寫新列的值。

數據庫中沒有主鍵。所以我不能提及一個單獨的行。要逐一讀取行,我必須做一個select *,這會給一個巨大的結果集(考慮數十億條記錄)。

有沒有更好的方法來做到這一點?

+1

您使用的是什麼RDBMS? – 2010-07-19 09:29:26

+0

答案似乎集中在切割小塊更新'...爲什麼阻止你做一個'更新'? – pascal 2010-07-19 09:37:14

+0

我沒有使用RDBMS。我正在使用基於MYSQL的列數據庫(Infinidb)。單次更新的問題是我將得到的巨大記錄集(大約100億條記錄),這些記錄集不適合RAM。 – Prashant 2010-07-19 09:57:09

回答

1

不同的DBMS具有不同的SQL方言,指定您在問題中使用的是有用的。

在SQL Server中,您可以使用Computed Column,但這會在每次選擇數據時計算結果,您可以將其標記爲持久,但可能需要一段時間才能進行更改。但是如果您要刪除舊列,則無法做到這一點。

或者創建新列允許空值,然後更新分批

UPDATE TOP (1000) table_name SET new_col1 = old_col1 + col_col2 WHERE new_col1 IS NULL

再次查詢是SQL Server,但會爲你的DBMS的替代品。

另請閱讀Hoopers先生關於向新列添加索引的評論,以確保隨着更多數據的添加,UPDATE的性能不會變差。更新是一個讀寫操作,索引會加快讀取速度並略微延遲寫入操作(保持索引),但這應該是值得的。

0

使用存儲過程,做一個更新其中的100個,添加存儲過程作爲一個工作運行,每說30秒。

+0

沒有主鍵,他怎麼會知道哪些hundered已經更新? – TheVillageIdiot 2010-07-19 09:26:33

+0

更新....限制100 - 只是假設這是mysql – 2010-07-19 09:29:38

+0

你是什麼意思的「做一個更新100他們」?有沒有辦法做100批記錄選擇? 類似的東西 - - select * from ... range 1 to 100 - select * from ... range 101 to 200 - select * from ... range 201 to 300 ... – Prashant 2010-07-19 09:44:11

1

我覺得Diver先生的方法會很好,如果你還在你的新列中添加了一個索引;否則,隨着工作的進展,它將不得不進行越來越多的掃描才能找到尚未更新的行。添加索引意味着它不必這樣做。一個可能的缺點是,創建列時索引差異會非常可怕,但我不認爲這會是一個問題,因爲您只關心NULL或NOT NULL。更新完成後,您可以刪除索引。