¿PostgreSQL optimiza la adición de columnas con valores predeterminados no NULL?

10

Al agregar NOT NULLcolumnas con un DEFAULTvalor, ¿PostgreSQL optimiza esta operación?

En el caso de que la tabla tenga n filas, una columna alter-table-add-column no optimizada produciría n escrituras del valor predeterminado, lo que obviamente podría ser muy doloroso. Con la optimización, la base de datos crearía instantáneamente la nueva columna, almacenaría solo una copia del valor predeterminado que se devolvería cuando no se encuentre un valor no predeterminado para esa columna en una estructura de datos de índice adecuada.

Por ejemplo, Oracle 11g tiene tal optimización .

maxschlepzig
fuente

Respuestas:

16

No existe tal mecanismo en PostgreSQL.

Sin embargo, aún puede evitar los efectos excesivos de dicho cambio de tabla.

La siguiente declaración adquiere un bloqueo de acceso exclusivo en la tabla durante la duración de la declaración / transacción:

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

Esta declaración cambia el catálogo, luego reescribe toda la tabla para que la nueva columna contenga el valor predeterminado en todas las filas. Si la tabla tiene muchas filas y se accede con suficiente frecuencia, esto podría causar algunos problemas temporales.

Para evitarlo, intente mantener el bloqueo exclusivo lo más corto posible:

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

Como esto es básicamente solo un cambio (en realidad dos) al catálogo (no ocurre ningún cambio de datos), se completará bastante rápido. Luego, según sus necesidades y el uso de la tabla, puede actualizar la nueva columna a la predeterminada en un solo paso o en lotes, y cuando haya terminado, configure la columna en NOT NULL.

Actualización sobre un deseo hecho realidad: PostgreSQL 11 tendrá esta característica. Ver https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ para más información.

dezso
fuente
4

Sí, con PostgreSQL 11

Esta característica es nueva y aterrizó en la Versión 11.

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

Lo anterior es uno de esos comandos que se verá afectado por esta optimización; pero, debe decirse NOT NULLque no se requiere. Cualquier columna nueva agregada con un valor predeterminado no nulo se optimiza ahora. Puede encontrar la entrada en este commitfest También debe consultar este gran artículo sobre él, "Un eslabón perdido en Postgres 11: Creación rápida de columnas con valores predeterminados" .

Solución previa a PostgreSQL 11

Si está tratando de evitar el bloqueo exclusivo de la mesa, siga los consejos de Craig Ringer,

  • Agregar una columna sin un DEFAULT
  • ALTERpara agregar DEFAULTluego para que se aplique a filas recién insertadas
  • Entonces poblar la nueva columna en las filas existentes por lotes progresivos UPDATEs
  • Cuando todas las filas tienen el valor, agrega la NOT NULLrestricción
Evan Carroll
fuente