列复制和更新与列创建和插入

时间:2015-05-12 16:47:20

标签: sql postgresql database-administration postgresql-performance bulkupdate

我在PostgreSQL 9.2.10中有一个包含3200万行和31列的表。我通过添加具有更新值的列来改变表格。

例如,如果初始表是:

id     initial_color
--     -------------
1      blue
2      red
3      yellow

我正在修改表格,结果是:

id     initial_color     modified_color
--     -------------     --------------
1      blue              blue_green
2      red               red_orange
3      yellow            yellow_brown

我的代码将读取initial_color列并更新值。

鉴于我的表有3200万行,并且我必须在31列中的5列上应用此过程,最有效的方法是什么?我目前的选择是:

  1. 复制列并更新新列中的行
  2. 创建一个空列并插入新值
  3. 我可以一次选择一列,也可以同时使用全部五列。列类型可以是character varyingcharacter

3 个答案:

答案 0 :(得分:3)

  

列类型可以是字符变量或字符。

不要使用character,这是一种误解。 varchar没问题,但我建议text使用任意字符数据。

  

鉴于我的表有3200万行,我必须应用它   对31个列中的5个列的程序,最有效的方法是什么?

如果您没有对象(视图,外键,函数),具体取决于现有表,最有效的方法是创建一个新表。这样的事情(细节取决于您的安装细节):

BEGIN;
LOCK TABLE tbl_org IN SHARE MODE;  -- to prevent concurrent writes

CREATE TABLE tbl_new (LIKE tbl_org INCLUDING STORAGE INCLUDING COMMENTS);

ALTER tbl_new ADD COLUMN modified_color text
            , ADD COLUMN modified_something text;
            -- , etc
INSERT INTO tbl_new (<all columns in order here>)
SELECT <all columns in order here>
    ,  myfunction(initial_color) AS modified_color  -- etc
FROM   tbl_org;
-- ORDER  BY tbl_id;  -- optionally order rows while being at it.

-- Add constraints and indexes like in the original table here

DROP tbl_org;
ALTER tbl_new RENAME TO tbl_org;
COMMIT;

如果您有依赖对象,则需要执行更多操作。

要么是,请务必添加all five at once。如果您在单独的查询中更新每个,由于Postgres的MVCC模型,您每次都会编写另一行版本。

相关案例,包含更多详细信息,链接和说明:

在创建新表时,您还可以优化方式对列进行排序:

答案 1 :(得分:2)

也许我误解了这个问题,但据我所知,你有2种可能来创建一个包含额外列的表:

  1. CREATE TABLE
    这将创建一个新表,并可以使用

    完成填充
    • CREATE TABLE .. AS SELECT..用于填充创作或
    • 稍后使用单独的INSERT...SELECT... 这两种变体都不是您想要做的,因为您声明解决方案而没有列出所有字段
      这也需要复制所有数据(加上新字段)。
  2. ALTER TABLE...ADD ...
    这将创建新列。由于我不知道有可能引用现有的列值,因此您需要额外的UPDATE ..SET...来填充值。

  3. 所以,我没有看到任何方法来实现一个符合你选择的程序1.

    然而,复制(列)数据只是为了在第二步中覆盖它们在任何情况下都是次优的。更改添加新列的表是最小的I / O.由此,即使有可能执行您的选择1,以下选择2也可以通过因子提供更好的性能。

    因此,做2个语句ALTER TABLE一次性添加所有新列,然后为UPDATE提供这些列的新值将达到您想要的效果。

答案 2 :(得分:0)

创建新列(修改后的颜色),它将在所有记录上具有NULL或空白值

运行更新声明,假设您的表名是&#39;表&#39;。

update table
set modified_color = 'blue_green'
where initial_color = 'blue'

如果我是正确的,这也可以像这样工作

update table set modified_color = 'blue_green' where initial_color = 'blue';
update table set modified_color = 'red_orange' where initial_color = 'red';
update table set modified_color = 'yellow_brown' where initial_color = 'yellow';

完成此操作后,您可以进行另一次更新(假设您有另一个我称之为modified_color1的列)

update table set 'modified_color1'= 'modified_color'