向具有数十亿行的列数据库添加新列

3
我想向一个已经包含数十亿行的表格中添加一个新列,这些新列是从现有列派生而来。
例如,
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 *,这会产生巨大的结果集(考虑到数十亿条记录)。
有更好的方法吗?

答案似乎集中在将UPDATE分成小块进行切割...为什么不能执行单个的UPDATE呢? - pascal
我没有使用关系型数据库。我正在使用基于MYSQL的列数据库(Infinidb)。单次更新的问题在于我会得到巨大的记录集(约100亿条记录),这些记录无法放入内存中。 - Prashant
好的,那是一个重要的细节... - pascal
3个回答

2
不同的数据库管理系统具有不同的SQL方言,指定你在问题中使用的方言是有用的。
在SQL Server中,您可以使用计算列,但这将在每次选择数据时计算结果,您可以标记它为持久化,但更改可能需要一段时间。但如果您要删除旧列,则无法这样做。
或者创建允许空值的新列,然后分批更新它们 UPDATE TOP (1000) table_name SET new_col1 = old_col1 + col_col2 WHERE new_col1 IS NULL 再次说明,此查询适用于SQL Server,但您的DBMS也会有其他替代方案。
还要阅读Hoopers先生关于向新列添加索引的评论,以确保UPDATE的性能随着添加更多数据而变差。更新是读取和写入操作,索引将加速读取并稍微延迟写入(维护索引),但应该是值得的。

1

我认为如果您在新列中添加一个索引,Diver先生的方法就会很好;否则,随着作业的进行,它将不得不做越来越多的扫描以找到尚未更新的行。添加索引意味着它不必这样做。可能的缺点是当创建列时索引差异会很大,但我认为这不会成为问题,因为您只关心NULL或NOT NULL。更新完成后,您可以删除索引。


0

使用存储过程,每次更新100个记录,将该存储过程添加为一个作业,每30秒运行一次。


没有主键,他怎么知道哪些百已经更新了? - TheVillageIdiot
“通过100个更新”是什么意思?有没有办法批量选择100条记录? 类似这样的操作 -
  • 从...范围1到100选择*
  • 从...范围101到200选择*
  • 从...范围201到300选择*...
- Prashant
是的,没有主键。LIMIT 100将返回一组随机行。我只想浏览表格并在浏览时更新新列值。 - Prashant
没有必要等待30秒。看起来这个问题只是为了节省内存,而不是在更新期间保持数据库的响应能力。 - pascal
仅作为示例,最多可以在2秒内更新100条记录(取决于数据),如果托管在良好的硬件上。 - Flakron Bytyqi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接