Re: [pgsql-ru-general] Добавить столбик одновременно заполняя значение

From: Sergey Konoplev <gray(dot)ru(at)gmail(dot)com>
To: "Dmitry E(dot) Oboukhov" <unera(at)debian(dot)org>
Cc: pgsql-ru-general <pgsql-ru-general(at)postgresql(dot)org>
Subject: Re: [pgsql-ru-general] Добавить столбик одновременно заполняя значение
Date: 2013-10-09 21:08:04
Message-ID: CAL_0b1ur5QH2Vy+CCbD8ds1pZ_x8wu4d-Urdxooj62THWhaRxA@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-ru-general

2013/10/9 Dmitry E. Oboukhov <unera(at)debian(dot)org>:
> есть задача которая решается как-то так
>
> BEGIN;
> ALTER TABLE "tbl" ADD COLUMN "bla";
> UPDATE "tbl" SET "bla" = "col1" + "col2";
> COMMIT;
>
> и обычно нас не парили такие апгрейды.
> но вот ща надо сапгрейдить большую табличку.
>
> ALTER по добавлению столбика занимает 1 минуту (2.5 млн записей)

Это странно. Наверное в оригинале добавляете колонку с DEFAULT и/или NOT NULL?

Ниже решение для общего случая, когда нужен и DEFAULT и NOT NULL и
миграция данных (не нужное убрать), с минимум блокировок.

ALTER TABLE tbl ADD col3 integer;

ALTER TABLE tbl ALTER col3 SET DEFAULT 123;

CREATE INDEX CONCURRENTLY tbl_migration_tmp
ON tbl (id) WHERE col3 IS NULL;

PSQL=psql
total_updated=0
updated=1
time (
while [ $updated -gt 0 ]; do
updated=$(($PSQL -X dbname <<EOF
UPDATE tbl SET col3 = least(col1, col2)
WHERE id IN (
SELECT id FROM tbl
WHERE col3 IS NULL LIMIT 1000);
EOF
) | cut -d ' ' -f 2)
(( total_updated+=updated ))
echo -ne "\r$total_updated"
done
) 2>&1

DROP INDEX tbl_migration_tmp;

ALTER TABLE tbl ALTER col3 SET NOT NULL;

--
Kind regards,
Sergey Konoplev
PostgreSQL Consultant and DBA

http://www.linkedin.com/in/grayhemp
+1 (415) 867-9984, +7 (901) 903-0499, +7 (988) 888-1979
gray(dot)ru(at)gmail(dot)com

In response to

Browse pgsql-ru-general by date

  From Date Subject
Next Message Konstantin Kubatkin 2013-10-30 13:17:12 UTF16
Previous Message Andrey Oktyabrskiy 2013-10-09 18:59:38 Re: Добавить столбик одновременно заполняя значение