PostgreSQL optimise-t-il l'ajout de colonnes avec des DEFAULT non NULL?

10

Lors de l'ajout de NOT NULLcolonnes avec une DEFAULTvaleur - PostgreSQL optimise-t-il cette opération?

Dans le cas où la table a n lignes, une colonne alter-table-add-optim non optimisée produirait n écrit de la valeur par défaut - ce qui pourrait être très douloureux, évidemment. Avec l'optimisation, la base de données créerait instantanément la nouvelle colonne, stockerait une seule copie de la valeur par défaut qui serait retournée lorsqu'aucune valeur non par défaut n'est trouvée pour cette colonne dans une structure de données d'index appropriée.

Par exemple, Oracle 11g a une telle optimisation .

maxschlepzig
la source

Réponses:

16

Il n'y a pas un tel mécanisme dans PostgreSQL.

Cependant, vous pouvez toujours éviter les effets excessifs d'un tel changement de table.

L'instruction suivante acquiert un verrou d'accès exclusif sur la table pour la durée de l'instruction / de la transaction:

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

Cette instruction modifie le catalogue, puis réécrit la table entière afin que la nouvelle colonne contienne la valeur par défaut dans toutes les lignes. Si la table comporte de nombreuses lignes et est consultée assez fréquemment, cela entraînerait des problèmes temporaires.

Pour l'éviter, essayez de maintenir le verrou exclusif aussi court que possible:

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

Comme il s'agit essentiellement d'une modification (en fait deux) du catalogue (aucun changement de données ne se produit), il se terminera assez rapidement. Ensuite, en fonction de vos besoins et de l'utilisation de la table, vous pouvez mettre à jour la nouvelle colonne par défaut en une seule étape ou par lots, et lorsque vous avez terminé, définissez la colonne sur NOT NULL.

Mise à jour sur un souhait devenu réalité: PostgreSQL 11 aura cette fonctionnalité. Voir https://www.depesz.com/2018/04/04/waiting-for-postgresql-11-fast-alter-table-add-column-with-a-non-null-default/ pour plus.

dezso
la source
4

Oui, avec PostgreSQL 11

Cette fonctionnalité est nouvelle et débarquée dans la version 11.

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

Ce qui précède est une de ces commandes qui sera affectée par cette optimisation; mais, il faut dire que ce NOT NULLn'est pas nécessaire. Toute nouvelle colonne ajoutée avec une valeur par défaut non nulle est maintenant optimisée. Vous pouvez trouver l'entrée dans ce commitfest. Vous devriez également consulter cette grande rédaction à ce sujet, "Un lien manquant dans Postgres 11: Création rapide de colonnes avec des valeurs par défaut" .

Solution de contournement pré-PostgreSQL 11

Si vous essayez d'éviter le verrou de table exclusif sur la table, suivez les conseils de Craig Ringer,

  • Ajouter une colonne sans DEFAULT
  • ALTERpour ajouter DEFAULTensuite pour qu'il s'applique aux lignes nouvellement insérées
  • Vous pouvez ensuite peupler la nouvelle colonne sur les lignes existantes par lots progressifs UPDATEs
  • Lorsque toutes les lignes ont la valeur que vous ajoutez la NOT NULLcontrainte
Evan Carroll
la source