Question

Je viens juste de transférer autant de données de structure de liens concernant wikipedia (anglais) que possible. En gros, j'ai téléchargé une série de dumps SQL à partir du dernier référentiel de dump de wikipedia. Étant donné que j'utilise PostgreSQL au lieu de MySQL, j'ai décidé de charger toutes ces sauvegardes dans ma base de données en utilisant pipeline commandes .

Quoi qu’il en soit, l’une de ces tables a 295 millions de lignes: la table pagelinks ; il contient tous les hyperliens intra-wiki. Depuis mon ordinateur portable, à l’aide de pgAdmin III, j’ai envoyé la commande suivante à mon serveur de base de données (un autre ordinateur):

SELECT pl_namespace, COUNT(*) FROM pagelinks GROUP BY (pl_namespace);

Cela fait environ une heure que ça dure. Le fait est que le maître de poste semble consommer de plus en plus de mon espace HD très limité. Je pense qu'il a mangé environ 20 Go à partir de maintenant. J'avais déjà joué avec le fichier postgresql.conf afin de lui donner plus de flexibilité en termes de performances (c'est-à-dire de le laisser utiliser plus de ressources) car il fonctionne avec 12 Go de RAM. Je pense que j'ai pratiquement quadruplé la plupart des octets et les variables liées de ce fichier en pensant qu'il utiliserait plus de RAM pour faire son travail.

Cependant, la base de données ne semble pas utiliser beaucoup de RAM. En utilisant le moniteur système Linux, je peux voir que le postmaster utilise 1,6 Go de mémoire partagée (RAM). Quoi qu'il en soit, je me demandais si vous pouviez m'aider à mieux comprendre ce que cela faisait, car il me semble que je ne comprends vraiment pas comment PostgreSQL utilise les ressources HD .

En ce qui concerne la métastructure des bases de données wikipedia, elles fournissent un bon schéma qui pourrait vous être utile ou qui pourrait vous intéresser.

N'hésitez pas à me demander plus de détails, merci

Était-ce utile?

La solution

C'est probablement le GROUP BY qui cause le problème. Pour effectuer un regroupement, la base de données doit trier les lignes afin de regrouper les éléments en double. Un index ne va probablement pas aider. Un calcul au dos de l'enveloppe:

En supposant que chaque ligne occupe 100 octets, il s’agit de 29 500 000 000 octets, soit environ 30 Go de stockage. Il ne peut pas contenir tout cela en mémoire, votre système est donc en train de se débattre, ce qui ralentit les opérations d'un facteur de 1 000 ou plus. Votre espace disque dur peut disparaître dans l’espace d’échange, s’il utilise des fichiers d’échange.

Si vous ne devez effectuer ce calcul qu’une seule fois, essayez de le diviser en sous-ensembles plus petits des données. En supposant que pl_namespace est numérique et va de 1 à 195 millions, essayez quelque chose comme ceci:

SELECT pl_namespace, COUNT(*)
FROM pagelinks
WHERE pl_namespace between 1 and 50000000
GROUP BY (pl_namespace);

Faites de même pour 50000001-100000000, etc. Combinez vos réponses ensemble en utilisant UNION ou simplement en un tableau avec un programme externe. Oubliez ce que j'ai écrit à propos d'un index qui n'aide pas GROUP BY; ici, un index aidera la clause WHERE.

Autres conseils

Qu'est-ce que exactement prétend qu'il ne faut que 9,5 Mo de RAM? Cela me semble peu probable - la mémoire partagée est presque certainement de la mémoire RAM partagée entre différents processus Postgres. (D'après ce que je me souviens, chaque client est un processus distinct, même si cela fait un moment que je risque de me tromper.)

Avez-vous un index sur la colonne pl_namespace ? S'il y a énormément de résultats distincts, j'imagine que la requête est assez lourde pour une table de 295 millions de lignes sans index. Cela dit, 10 Go, c'est beaucoup à avaler. Savez-vous quels fichiers il écrit?

Ok, voici l'essentiel:

la clause GROUP BY a invalidé l'index, le postmaster (processus serveur postgresql) a donc décidé de créer un ensemble de tables (23 Go de tables) situées dans le répertoire $ PGDATA / base / 16384 / pgsql_tmp.

Lors de la modification du fichier postgresql.conf, j’avais donné à PostgreSQL la permission d’utiliser 1,6 Go de RAM (que je vais doubler car il a accès à 11,7 Go de RAM); le processus postmaster utilisait bien 1,6 Go de RAM, mais cela ne suffisait pas, ainsi le répertoire pgsql_tmp.

Comme Barry Brown l’a souligné, comme j’exécutais cette commande SQL uniquement pour obtenir des informations statistiques sur la distribution des liens entre les pagelinks.namespaces , j’aurais pu interroger un sous-ensemble de les 296 millions pagelinks (c’est ce qu’ils font pour les enquêtes).

Lorsque la commande a renvoyé le jeu de résultats, toutes les tables temporaires ont été automatiquement supprimées comme si de rien n'était.

Merci pour votre aide les gars!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top