Vaut-il mieux créer un index avant de remplir une table avec des données, ou après que les données sont en place?

87

J'ai une table d'environ 100 millions de lignes que je vais copier pour modifier, en ajoutant un index. Je ne suis pas tellement préoccupé par le temps qu'il faut pour créer la nouvelle table, mais l'index créé sera-t-il plus efficace si je modifie la table avant d'insérer des données ou d'insérer les données en premier, puis d'ajouter l'index?

Drew Stephens
la source

Réponses:

113

La création d'un index après l'insertion de données est un moyen plus efficace (il est même souvent recommandé de supprimer l'index avant l'importation par lots et de le recréer après l'importation).

Exemple de syntaxe (PostgreSQL 9.1, machine de développement lent, un million de lignes):

CREATE TABLE test1(id serial, x integer);
INSERT INTO test1(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 7816.561 ms
CREATE INDEX test1_x ON test1 (x);
-- Time: 4183.614 ms

Insérer puis créer un index - environ 12 sec

CREATE TABLE test2(id serial, x integer);
CREATE INDEX test2_x ON test2 (x);
-- Time: 2.315 ms
INSERT INTO test2(id, x) SELECT x.id, x.id*100 FROM generate_series(1,1000000) AS x(id);
-- Time: 25399.460 ms

Créez un index, puis insérez-le - environ 25,5 secondes (plus de deux fois plus lentement)

Valodzka
la source
5
+1, les index ralentiront nettement une opération impliquant une tâche d'insertion de 100 millions de lignes, il vaut donc mieux les supprimer et les recréer.
code4life
10

Il est probablement préférable de créer l'index après l'ajout des lignes. Non seulement ce sera plus rapide, mais l'équilibrage des arbres sera probablement meilleur.

Modifier «équilibrage» n'est probablement pas le meilleur choix de termes ici. Dans le cas d'un arbre b, il est équilibré par définition. Mais cela ne signifie pas que le b-tree a la disposition optimale. La distribution des nœuds enfants au sein des parents peut être inégale (entraînant des coûts plus élevés dans les futures mises à jour) et la profondeur de l'arborescence peut finir par être plus profonde que nécessaire si l'équilibrage n'est pas effectué avec soin lors des mises à jour. Si l'index est créé après l'ajout des lignes, il aura probablement une meilleure distribution. En outre, les pages d'index sur le disque peuvent avoir moins de fragmentation après la création de l'index. Un peu plus d'informations ici

Mark Wilkins
la source
2

Cela n'a pas d'importance sur ce problème car:

  1. Si vous ajoutez d'abord des données à la table et après cela, vous ajoutez un index. Votre temps de génération d'index sera plus O(n*log(N))long (où nest ajoutée une ligne). Parce que le temps de gérance de l'arbre est O(N*log(N))alors si vous divisez cela en anciennes données et en nouvelles données, vous O((X+n)*log(N))pouvez simplement les convertir O(X*log(N) + n*log(N))et dans ce format, vous pouvez simplement voir ce que vous attendez de plus.
  2. Si vous ajoutez un index et après, mettez des données. Chaque ligne (vous avez de nnouvelles lignes) vous obtenez plus de temps d'insertion supplémentaire O(log(N))nécessaire pour régénérer la structure de l'arborescence après y avoir ajouté un nouvel élément (colonne d'index à partir de la nouvelle ligne, car l'index existe déjà et une nouvelle ligne a été ajoutée, l'index doit être régénéré à équilibré structure, ce coût O(log(P))Pest une puissance d'index [éléments dans l'index] ). Vous avez de nnouvelles lignes puis enfin vous avez n * O(log(N))ensuite O(n*log(N))résumé du temps supplémentaire.
Svisstack
la source
1

Les index créés après sont beaucoup plus rapides dans la plupart des cas. Exemple: 20 millions de lignes avec texte intégral sur varchar (255) - (Nom de l'entreprise) Index en place lors de l'importation de lignes - une correspondance qui prend jusqu'à 20 secondes dans le pire des cas. Supprimez l'index et recréez-le - match contre moins d'une seconde à chaque fois

Mike Cross
la source
-2

Je ne suis pas sûr que ce soit vraiment important pour l'efficacité de l'index, car dans les deux cas, vous insérez de nouvelles données dans l'index. Le serveur ne saurait à quel point un index serait déséquilibré avant sa construction, en gros. En termes de vitesse, évidemment, faites les inserts sans index.

Grand maîtreB
la source