web-dev-qa-db-fra.com

Le moyen le plus efficace de créer un index dans Postgres

Est-il plus efficace de créer un index une fois le chargement des données terminé ou avant, ou cela n'a-t-il pas d'importance?

Par exemple, disons que j'ai 500 fichiers à charger dans une base de données Postgres 8.4. Voici les deux scénarios de création d'index que je pourrais utiliser:

  1. Créez un index lorsque la table est créée, puis chargez chaque fichier dans la table; ou
  2. Créez un index une fois que tous les fichiers ont été chargés dans la table.

Les données de la table sont d'environ 45 gigaoctets. L'index est d'environ 12 gigaoctets. J'utilise un index standard. Il est créé comme ceci:

CREATE INDEX idx_name ON table_name (column_name);

Mon chargement de données utilise COPY FROM .

Une fois tous les fichiers chargés, aucune mise à jour, suppression ou chargement supplémentaire ne se produira sur la table (c'est une journée de données qui ne changera pas). Je voulais donc demander quel scénario serait le plus efficace? Les tests initiaux semblent indiquer que le chargement de tous les fichiers puis la création de l'index (scénario 2) est plus rapide, mais je n'ai pas fait de comparaison scientifique des deux approches.

43
user1356386

Votre observation est correcte - il est beaucoup plus efficace de charger les données en premier et ensuite de créer un index. La raison en est que les mises à jour d'index pendant l'insertion sont coûteuses. Si vous créez un index une fois que toutes les données sont là, c'est beaucoup plus rapide.

Cela va encore plus loin: si vous devez importer une grande quantité de données dans une table indexée existante, il est souvent plus efficace de supprimer d'abord l'index existant, d'importer les données, puis de recréer à nouveau l'index.

Un inconvénient de la création d'un index après l'importation est que la table doit être verrouillée, ce qui peut prendre du temps (elle ne sera pas verrouillée dans le scénario opposé). Mais, dans PostgreSQL 8.2 et versions ultérieures, vous pouvez utiliser CREATE INDEX CONCURRENTLY , qui ne verrouille pas la table pendant l'indexation (avec quelques mises en garde).

72
mvp