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. 空の列を作成して新しい値を挿入する

一度に 1 つの列を使用するか、5 つすべてを一度に使用するかのいずれかのオプションを実行できます。列のタイプは または のいずれ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 に答える