Puisque Postgres ne peut ajouter que des colonnes à la fin des tables, je finis par réorganiser en ajoutant de nouvelles colonnes à la fin de la table, en les définissant égales aux colonnes existantes, puis en supprimant les colonnes d'origine. Alors, que fait PostgreSQL avec la mémoire libérée par les colonnes supprimées? Est-ce qu'il réutilise automatiquement la mémoire, de sorte qu'un seul enregistrement consomme la même quantité d'espace qu'avant? Mais cela nécessiterait une réécriture de toute la table, donc pour éviter cela, garde-t-il juste un tas d'espace vide autour de chaque enregistrement?Quel est l'effet sur la taille de l'enregistrement des colonnes de réorganisation dans PostgreSQL?
Quel est l'effet sur la taille de l'enregistrement des colonnes de réorganisation dans PostgreSQL?
Répondre
De l'docs:
Le formulaire
DROP COLUMN
ne supprime pas physiquement la colonne, mais simplement le rend invisible aux opérations SQL. Les opérations d'insertion et de mise à jour suivantes dans la table stockent une valeur null pour la colonne. Ainsi, la suppression d'une colonne est rapide, mais elle ne réduit pas immédiatement la taille sur le disque de votre table, car l'espace occupé par la colonne supprimée n'est pas récupéré. L'espace sera récupéré au fur et à mesure que les lignes existantes seront mises à jour.
Vous devrez effectuer un CLUSTER
suivi d'un VACUUM FULL
pour récupérer l'espace.
Pourquoi "commandez-vous"? Il n'y a pas d'ordre en SQL, ça ne fait pas de sens. Si vous avez besoin d'une commande fixe, indiquez à vos requêtes l'ordre dont vous avez besoin ou utilisez une vue, c'est ce que les vues sont faites. Espace disque sera utilisé à nouveau après le vide, auto_vacuum fera le travail.
Sauf si vous avez désactivé ce processus. Votre approche actuelle va tuer les performances globales (verrous de table), les index doivent être recréés, les statistiques vont dans les toilettes, etc. Et au final, vous finissez avec la même situation que vous avez déjà eue. Alors pourquoi l'effort?
Je m'attendais à ce que cela se produise. J'aime que mes colonnes soient dans un ordre qui ait du sens pour les humains, comme moi. Tant qu'il ne prend pas trop d'espace disque (ce qui ne sera pas le cas après un vide complet). Juste une préférence personnelle. :) – Summer
Vous ne devriez pas vous fier à l'ordre implicite des colonnes, tout comme vous ne devriez pas compter sur l'ordre implicite des lignes dans les requêtes sans ORDER BY. Cela signifie-t-il que vos applications utilisent SELECT * et INSERT INTO table VALUES, sans les noms de champs? Parce que ce serait juste demander des ennuis. Si vous souhaitez un ordre de colonne spécifique, créez une vue avec cet ordre. – MkV
J'ai besoin de réorganiser parce que c'est juste plus facile de regrouper certaines colonnes! Je n'arrive pas à croire que quelque chose de fondamental comme celui-ci ne soit pas supporté dans Postgres ... BIEN SÛR Je ne m'appuie pas sur l'ordre des colonnes dans le tableau, mais c'est plus facile lors de la conception de la base de données! Pourquoi tous ces nerds de Linux ne comprennent-ils pas cela ?! Les gens utilisent les GUI de nos jours! C'est 2011! – Dylan
La question est ancienne, mais comme les deux réponses sont fausses ou trompeuses, j'en ajouterai une autre. Lors de la mise à jour d'une ligne, Postgres écrit une nouvelle version de ligne et l'ancienne est finalement supprimée par VACUUM
après qu'aucune transaction en cours ne peut plus la voir.
Le plain VACUUM
ne renvoie pas l'espace disque du fichier physique qui contient la table au système, sauf s'il trouve des blocs complètement morts ou vides à l'extrémité physique de la table. Vous devez exécuter VACUUM FULL
ou CLUSTER
pour compacter agressivement la table et retourner l'espace excédentaire au système. Ceci n'est généralement pas souhaitable en fonctionnement normal. Postgres peut réutiliser des tuples morts pour conserver les nouvelles versions de ligne sur la même page de données, ce qui améliore les performances.
Dans votre cas, puisque vous mettez à jour chaque ligne, la taille de la table est doublée (à partir de sa taille minimum). Il est conseillé d'exécuter VACUUM FULL
ouCLUSTER
pour renvoyer le ballonnement au système.
Les deux prennent un verrou exclusif sur la table. Si cela interfère avec l'accès concurrent, considérez pg_repack
, qui peut faire la même chose sans verrous exclusifs.
Pour clarifier: Exécuter CLUSTER
récupère l'espace complètement.No VACUUM FULL
is needed after CLUSTER
(and vice versa).
Plus de détails:
, VACUUM FULL ne récupérer l'espace si chaque ligne est mis à jour, il nettoie après les lignes complètement mortes - colonnes pas mortes dans de bonnes lignes autrement. Puisque la mise à jour qui définit la nouvelle colonne doit avoir lieu avant de faire le DROP, l'espace occupé par la colonne maintenant obsolète ne sera pas récupéré par elle. Seule l'ancienne copie originale de la ligne sera nettoyée. En plus d'une mise à jour totale, vous pouvez exécuter CLUSTER (dans PostgreSQL 8.3 ou ultérieur) ou créer une nouvelle copie de la table (quelque chose comme CREATE TABLE AS) et mélanger les noms afin de vous débarrasser de l'espace occupé par les morts colonnes. –
@Greg: bon point. – Quassnoi
@Summer: 'CLUSTER' réécrit toute la table (plus les index), optimisant ainsi parfaitement la table. 'VACUUM FULL' est redondant après' CLUSTER'. Vous pourriez vouloir exécuter 'ANALYZE'. Cette réponse est incorrecte (sauf pour la citation). J'ai ajouté une réponse pour clarifier. –