0
votes

Mise à jour groupée de la table Postgres

J'ai une table avec environ 200 millions d'enregistrements et j'ai ajouté 2 nouvelles colonnes à elle. Maintenant, les 2 colonnes ont besoin de valeurs d'une table différente. Près de 80% des lignes seront mises à jour.

J'ai essayé la mise à jour mais elle prend plus de 2 heures à compléter.

La table principale a une clé primaire composite de 4 colonnes. Je l'ai laissé tomber et j'ai laissé tomber un index présent sur une colonne avant de mettre à jour. Maintenant, la mise à jour prend peu de plus d'une heure.

y a-t-il d'autre moyen d'accélérer ce processus de mise à jour (comme le traitement par lots).

Edit: j'ai utilisé l'autre table (à partir de laquelle les valeurs seront assorties pour la mise à jour) de la clause de la relève de la mise à jour.


0 commentaires

3 Réponses :


1
votes

Pas vraiment. Assurez-vous que max_wal_size est suffisamment élevé pour ne pas avoir trop de points de contrôle.

Après la mise à jour, la table sera gonflée à environ deux fois sa taille d'origine. Ce gonflement peut être évité si vous mettez à jour par lots et VACUUM entre les deux, mais cela ne rendra pas le traitement plus rapide.


0 commentaires

1
votes

Avez-vous besoin d'une mise à jour complète en une seule transaction? J'ai eu un problème assez similaire, avec une table qui était sous forte charge et la colonne ne nécessitait pas de contrainte nulle. Traitez-le - j'ai fait quelques étapes:

  1. Ajoutez des colonnes sans contraintes comme non nulles, mais avec des valeurs par défaut. De cette façon, tout s'est déroulé très vite.
  2. Mettez à jour les colonnes par étapes telles que 1 000 entrées par transaction. Dans mon cas, la charge de la DB monte, j'ai donc dû mettre un petit retard.
  3. Mettez à jour les colonnes pour qu'elles ne contiennent pas de contraintes nulles.

De cette façon, vous ne bloquez pas la table pendant longtemps, mais ce n'est pas une réponse à votre question.

D'abord pour valider où vous êtes - je vérifierais iostats pour voir si ce n'est pas la limite ... Pour accélérer, je considérerais:

  • carte d'espace libre plus élevée - pour être sûr que DB est conscient des entrées qui peuvent être supprimées, mais notez que si les pages sont compactées à la limite, cela n'apportera pas grand-chose ...
  • peut-être que les clés étrangères faisant référence à la table peuvent également être supprimées? Pour arrêter de verrouiller le tableau,
  • supprimer tous les index car ils ralentissent et les créer après - cela ressemble à un problème de découpage mais autrement, mais c'est une option, donc ça compte ...

2 commentaires

Merci. Pouvez-vous me dire comment faire comme 1000 entrées par transaction? Ici, ma clé primaire a 4 colonnes.


@Manoharan stackoverflow.com/questions / 22351039 /… - vous ne pouvez pas faire ça directement depuis PG - J'ai un script Python pour ça ...



1
votes

Il existe deux types de solution à votre problème.

1) Cette approche fonctionne si votre table principale n'est pas mise à jour ou insérée pendant ce processus

  1. Commencez par créer le même schéma de table sans clé primaire composite et index avec un nom différent.
  2. Insérez ensuite les données dans la nouvelle table avec les données de la table de jointure.
  3. Appliquez toutes les contraintes et tous les index sur la nouvelle table après l'insertion.
  4. Supprimez l'ancienne table et renommez la nouvelle table avec l'ancien nom de table.

2) Ou vous pouvez utiliser un déclencheur pour mettre à jour ces deux colonnes lors de l'insertion ou de la mise à jour de l'événement. (Cela ralentira légèrement l'opération d'insertion de mise à jour)


1 commentaires

Merci beaucoup pour cette suggestion. Je vais essayer de publier si cela réduit le temps d'exécution.