Tôt le matin, un travail pgAgent actualise le contenu du tableau A à partir du tableau B sur ma base de données PostgreSQL 8.4. Le tableau A contient environ 140k enregistrements sur 91 colonnes et possède deux index - l'un faisant partie de la CLÉ PRIMAIRE et l'autre un index GIST sur une colonne de géométrie POINT PostGIS.
Pour accélérer le processus, le travail supprime l'index sur la colonne de géométrie, avant de supprimer les enregistrements de la table A et d'insérer les enregistrements de la table B, puis l'index est recréé. Tout cela étant fait, le démon autovacuum se met au travail quand il en a envie (après une dizaine de minutes de comparaison des statistiques de travail et des statistiques de table pour le temps de fin du travail et le temps d'exécution autovacuum).
Après avoir vérifié sur la table ce matin après tout ce qui s'était passé, les statistiques de la table m'ont dit que la taille de la table était de 272 Mo, la taille de la table TOAST était de 8192 octets et la taille de l'index était de 23 Mo. Cela semblait assez important, j'ai donc émis une commande REINDEX sur la table et la taille de l'index est descendue à 9832 Ko.
Ma (mes) question (s) est la suivante:
Pourquoi le REINDEX réduit-il apparemment la taille des index si les index (ou du moins l'index de la colonne de géométrie) ont été reconstruits à partir de zéro? Dois-je m'assurer que la table a été aspirée / analysée avant la construction des index? La suppression de l'index sur la clé primaire n'est-elle pas un facteur à cet égard? Qu'est-ce que je rate?
la source
ANALYZE
la taille signalée diminue également.Réponses:
Si l'instruction CREATE INDEX constate qu'une autre session contient un instantané actif qui pourrait toujours être intéressé par les enregistrements supprimés, elle inclut ces enregistrements supprimés dans le nouvel index.
De même, si un REINDEX voit qu'une autre session contient un instantané actif qui pourrait toujours être intéressé par les enregistrements supprimés, il inclut ces enregistrements supprimés dans le nouvel index.
Si un ASPIRATEUR voit qu'une autre session contient un instantané actif qui pourrait toujours être intéressé par les enregistrements supprimés, il conserve ces enregistrements dans la table. Et puis le REINDEX ou CREATE INDEX doivent également les porter dans le nouvel index, tant que l'instantané existe toujours.
Une fois qu'il n'y a plus d'instantanés qui pourraient voir les lignes supprimées, le VACUUM peut les supprimer de la table. Mais un CREATE INDEX ou REINDEX ne pouvait tout simplement pas les reporter dans le nouvel index, que VACUUM ait réussi à les supprimer des capables ou non.
Donc, dans votre scénario, le rôle de la fonction VIDE entre le CREATE INDEX et le REINDEX initial est probablement juste de prendre du temps, pendant lequel votre transaction de longue durée disparaît d'elle-même et laisse tomber l'instantané interférant.
la source
Après avoir essayé différents ordres de choses, il semble que l'exécution d'un VACUUM avant une instruction REINDEX soit le seul moyen d'obtenir la réduction de taille, peut-être parce que l'espace non aspiré ajoute à l'index (indexation des enregistrements supprimés?). Forcer la réécriture d'une table à l'aide de
fait le même genre de chose, car il efface l'espace désaffecté.
Le fait d'avoir à VACUUM au milieu du processus rompt un peu le flux car il faut émettre une commande VACUUM en dehors d'une transaction.
la source