Оптимизирует ли PostgreSQL добавление столбцов с ненулевыми значениями по умолчанию?

10

При добавлении NOT NULLстолбцов со DEFAULTзначением - оптимизирует ли PostgreSQL эту операцию?

Если в таблице n строк, неоптимизированный столбец alter-table-add-column даст n записей значения по умолчанию, что, очевидно, может быть очень болезненным. При оптимизации БД мгновенно создаст новый столбец, сохранит только одну копию значения по умолчанию, которое будет возвращено, если для этого столбца не найдено значение, отличное от значения по умолчанию, в подходящей структуре данных индекса.

Например, Oracle 11g имеет такую оптимизацию .

maxschlepzig
источник

Ответы:

16

В PostgreSQL такого механизма нет.

Тем не менее, вы все равно можете избежать чрезмерных последствий такого изменения таблицы.

Следующий оператор получает исключительную блокировку доступа к таблице на время оператора / транзакции:

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Этот оператор изменяет каталог, затем переписывает всю таблицу так, чтобы новый столбец содержал значение по умолчанию во всех строках. Если в таблице много строк и доступ к ней осуществляется достаточно часто, это может вызвать некоторые временные проблемы.

Чтобы избежать этого, старайтесь держать эксклюзивную блокировку как можно короче:

ALTER TABLE your_table
    ADD COLUMN new_column integer;
ALTER TABLE your_table
    ALTER COLUMN new_column SET DEFAULT 0;

Поскольку это в основном только (фактически два) изменения в каталоге (никаких изменений данных не происходит), оно будет выполнено довольно быстро. Затем, в зависимости от ваших потребностей и использования таблицы, вы можете обновить новый столбец до значения по умолчанию за один шаг или партиями, а когда закончите, установите для столбца значение NOT NULL.

Обновление о желании сбывается: PostgreSQL 11 будет иметь эту функцию. См. Https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ для получения дополнительной информации.

Dezso
источник
4

Да, с PostgreSQL 11

Эта функция является новой и появилась в версии 11.

ALTER TABLE your_table
    ADD COLUMN new_column integer NOT NULL DEFAULT 0;

Выше приведена одна из таких команд, которая будет затронута этой оптимизацией; но, следует сказать, что NOT NULLэто не обязательно. Любой новый столбец, добавленный с ненулевым значением по умолчанию, теперь оптимизирован. Вы можете найти запись в этом коммит-фесте. Вы также должны проверить эту замечательную статью об этом, «Недостающее звено в Postgres 11: Быстрое создание столбцов со значениями по умолчанию» .

Пре-PostgreSQL 11 Обходной путь

Если вы пытаетесь избежать эксклюзивной блокировки на столе, следуйте советам Крейга Рингера,

  • Добавить столбец без DEFAULT
  • ALTERэто добавить DEFAULTпотом, так что это относится к вновь вставленным строкам
  • Затем заполнить новый столбец на существующих строках прогрессивных пакетных UPDATEс
  • Когда все строки имеют значение, вы добавляете NOT NULLограничение
Эван Кэрролл
источник