2

我在 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. 创建一个空列并插入新值

我可以一次选择一列,也可以一次选择全部五列。列类型为character varyingcharacter

4

3 回答 3

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 模型,您每次都会编写另一个行版本。

相关案例及更多细节、链接和解释:

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

于 2016-04-08T13:45:52.037 回答
2

也许我误读了这个问题,但据我所知,您有 2 种可能性来创建带有额外列的表:

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

    • CREATE TABLE .. AS SELECT..充满创造或
    • 稍后使用单独INSERT...SELECT...的两种变体似乎都不是您想要做的,因为您在没有列出所有字段的情况下陈述了解决方案
      这也需要复制所有数据(加上新字段)。
  2. ALTER TABLE...ADD ...
    这将创建新列。由于我不知道引用现有列值的任何可能性,因此您将需要额外UPDATE ..SET...的值来填充值。

所以,我没有看到任何方法来实现遵循您的选择 1 的程序。

然而,复制(列)数据只是为了在第二步中覆盖它们在任何情况下都是次优的。更改表添加新列正在执行最少的 I/O。由此看来,即使有可能执行您的选择 1,遵循选择 2 也可以保证按因素获得更好的性能。

因此,执行 2 条语句,其中一条ALTER TABLE在运行中添加所有新列,然后UPDATE为这些列提供新值将实现您想要的。

于 2016-04-07T14:46:50.247 回答
0

创建新列(修改颜色),所有记录的值为 NULL 或空白,

运行更新语句,假设您的表名是“表”。

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'
于 2016-04-08T04:41:27.407 回答