Производительность всегда будет зависеть, ваша цель - сделать ACCESS EXCLUSIVE
блокировки как можно короче.
Итак
добавить столбец bigint
без значения по умолчанию
создать последовательность OWNED BY
новый столбец
использовать ALTER TABLE
для установки значения по умолчанию для столбца с помощью последовательность
обновляет значения NULL в новом столбце из последовательности
Это следует делать пакетами, чтобы избежать одновременной блокировки слишком большого количества строк.
создать уникальный индекс для нового столбца CONCURRENTLY
добавить уникальное ограничение с использованием нового индекса
Это не даст вам первичный ключ, потому что вы все еще пропускаете ограничение NOT NULL
. Невозможно установить столбец NOT NULL
без сканирования всей таблицы, которая будет удерживать блокировку ACCESS EXCLUSIVE
в течение более длительного времени. Однако, если вам нужен истинный первичный ключ, вы не можете этого избежать.
Вот моя процедура в SQL с использованием примера таблицы:
ALTER TABLE x ADD id bigint;
CREATE SEQUENCE x_id_seq OWNED BY x.id;
ALTER TABLE x ALTER id SET DEFAULT nextval('x_id_seq');
UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
AND somecol BETWEEN 1 AND 10000;
UPDATE x SET id = nextval('x_id_seq')
WHERE id IS NULL
AND somecol BETWEEN 10001 AND 20000;
...
CREATE UNIQUE INDEX CONCURRENTLY x_id_idx ON x(id);
ALTER TABLE x ADD UNIQUE USING INDEX x_id_idx;
Я надеюсь, что в следующий раз вы узнаете лучше, и вы никогда больше не создадите таблицу без первичного ключа.