13.4. Remplir une base de données

Vous pourriez avoir besoin d'insérer un grand nombre de données pour remplir une base de données au tout début. Cette section contient quelques suggestions pour réaliser cela de la façon la plus efficace.

13.4.1. Désactivez la validation automatique (autocommit)

Désactivez la validation automatique et faites une seule validation à la fin. (En SQL, ceci signifie de lancer BEGIN au début et COMMIT à la fin. Quelques bibliothèques client pourraient le faire derrière votre dos auquel cas vous devez vous assurer que la bibliothèque le fait quand vous le voulez.) Si vous permettez à chaque insertion d'être validée séparément, PostgreSQL fait un gros travail pour chaque ligne ajoutée. Un bénéfice supplémentaire de réaliser toutes insertions dans une transaction est que si l'insertion d'une ligne échoue alors les lignes insérées jusqu'à maintenant seront annulées. Vous ne serez donc pas bloqué avec des données partiellement chargées.

13.4.2. Utilisez COPY

Utilisez COPY pour charger toutes les lignes en une seule commande, plutôt que d'utiliser une série de commandes INSERT. La commande COPY est optimisée pour charger un grand nombre de lignes ; elle est moins flexible que INSERT mais introduit significativement moins de surcharge lors du chargement de grosses quantités de données. Comme COPY est une seule commande, il n'y a pas besoin de désactiver la validation automatique (autocommit) si vous utilisez cette méthode pour remplir une table.

Si vous ne pouvez pas utiliser COPY, utiliser PREPARE pourrait vous aider à créer une instruction préparée INSERT, puis utilisez EXECUTE autant de fois que nécessaire. Ceci évite certaines surcharges lors d'une analyse et d'une planification répétées de commandes INSERT.

Notez que charger un grand nombre de lignes en utilisant COPY est pratiquement toujours plus rapide que d'utiliser INSERT, même si PREPARE est utilisé lorsque de nombreuses insertions sont groupées en une seule transaction.

13.4.3. Supprimez les index

Si vous chargez une table tout juste créée, la façon la plus rapide est de créer la table, de charger en lot les données de cette table en utilisant COPY, puis de créer tous les index nécessaires pour la table. Créer un index sur des données déjà existantes est plus rapide que de mettre à jour de façon incrémentale à chaque ligne ajoutée.

Si vous augmentez une table existante, vous pouvez supprimer les index, charger la table, puis recréer l'index. Bien sûr, les performances de la base de données pour les autres utilisateurs pourraient être sévèrement affectées tout le temps où l'index sera manquant. Vous devez aussi y penser à deux fois avant de supprimer des index uniques car la vérification d'erreur apportée par la contrainte unique sera perdue tout le temps où l'index est manquant.

13.4.4. Augmentez maintenance_work_mem

Augmentez temporairement la variable maintenance_work_mem lors du chargement de grosses quantités de données peut amener une amélioration des performances. Ceci est dû au fait qu'un index B-tree est créé à partir de rien, le contenu déjà existant de la table a besoin d'être trié. Permettre au tri merge d'utiliser plus de mémoire signifie que moins de passes merge seront requises. Une grande valeur pour maintenance_work_mem pourrait aussi accélérer la validation des contraintes de clés étrangères.

13.4.5. Augmentez checkpoint_segments

Augmenter temporairement la variable de configuration checkpoint_segments peut aussi aider à un chargement rapide de grosses quantités de données. Ceci est dû au fait que charger une grosse quantité de données dans PostgreSQL peut causer la venue trop fréquentes de points de vérification (la fréquent de ces points de vérification est spécifiée par la variable de configuration checkpoint_timeout). Quand survient un point de vérification, toutes les pages modifiées sont écrites sur le disque. En augmentant checkpoint_segments temporairement lors du chargement des données, le nombre de points de vérification requis peut être diminué.

13.4.6. Lancez ANALYZE après

Quand vous avez changé significativement la distribution des données à l'intérieur d'une table, lancer ANALYZE est fortement recommandée. Ceci inclut le chargement de grosses quantités de données dans la table. Lancer ANALYZE (ou VACUUM ANALYZE) vous assure que le planificateur dispose de statistiques à jour sur la table. Sans statistiques ou avec des statistiques obsolètes, le planificateur pourrait prendre de mauvaises décisions lors de la planification de la requête, amenant des performances pauvres sur toutes les tables sans statistiques ou avec des statistiques inexactes.