2010-07-19 26 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。更新完成后,您可以删除索引。