PostgreSQL La base de donnees la plus sophistiquee au monde.

Forums PostgreSQL.fr

Le forum officiel de la communauté francophone de PostgreSQL

Vous n'êtes pas identifié(e).

#1 07/10/2010 11:21:43

jhashe
Membre

Besoin d'éclaircissement sur plan d'analyse

Bonjour,

Je rencontre une situation que je ne comprends pas:

Je veux exécuter la requête suivante:
SELECT * FROM indexation.lot_index WHERE id_lot IN (167582,167586)

La table en question possède un index sur id_lot
CREATE INDEX idx_lot_lot_index
  ON indexation.lot_index
  USING btree
  (id_lot);

Or, le plan d'exécution de cette requête est:
"Seq Scan on lot_index  (cost=0.00..397340.40 rows=22064588 width=536)"
"  Filter: (id_lot = ANY ('{167582,167586}'::integer[]))"

Résultat, l'exécution de cette requête pourtant simple demande plusieurs dizaines de minutes.

Bien entendu, j'ai relancé un ANALYZE sur la table en question, sans succès.


Il y  a sûrement une subtilité qui m'échappe, mais... laquelle ?

Hors ligne

#2 07/10/2010 12:00:12

Marc Cousin
Membre

Re : Besoin d'éclaircissement sur plan d'analyse

Il estime que id_lot IN (167582,167586) va ramener 22064588 enregistrements.

Il a faux ?


Marc.

Hors ligne

#3 07/10/2010 12:03:01

gleu
Administrateur

Re : Besoin d'éclaircissement sur plan d'analyse

Et il y a combien de lignes dans cette table ?


Guillaume.

Hors ligne

#4 08/10/2010 09:02:52

jhashe
Membre

Re : Besoin d'éclaircissement sur plan d'analyse

L'estimation du nombre d'enregistrements retournés était bonne.
Ma question est plutôt, pourquoi il n'utilise pas l'index car, ici, cette requête mettait plus de 3 minutes pour s'exécuter (serveur bi quad-xeon avec 32Go de RAM)
(évidemment, je ne tiens pas compte ensuite du temps de lecture du recordset...)

De plus, la "vraie" requête était du style

insert into ma_table SELECT * FROM indexation.lot_index WHERE id_lot IN (167582,167586)

Je l'ai interrompue après plus de 2 heures d'exécution !

Remarque complémentaire, probablement liée; en exécutant le "SELECT * FROM indexation.lot_index WHERE id_lot IN (167582,167586)", parfois, j'obtenais un résultat, parfois un "Out of memory error" ?!?

Pour être tout-à-fait complet, j'ai modifié mon traitement, et je n'ai plus besoin des requêtes évoquées ici, mais je suis tout de même intrigué !

Dernière modification par jhashe (08/10/2010 09:04:28)

Hors ligne

#5 08/10/2010 09:11:34

Marc Cousin
Membre

Re : Besoin d'éclaircissement sur plan d'analyse

Si l'estimation est bonne, le moteur a fait le bon choix: il est plus rapide de lire séquentiellement toute une table quand une grande partie de celle-ci est retournée par une requête, que de la lire en passant par un index. Il est très improbable que vous puissiez récupérer 22 millions d'enregistrements par un scan d'index en 3 minutes (comptez plutôt 3 heures).

L'insert lui même était probablement très lent si la table de destination (ma_table) a beaucoup d'index.

Pour le Out of memory error, c'est normal: par défaut, psql récupère l'ensemble des enregistrements en mémoire avant de les afficher. C'est psql (l'application cliente) qui faisait un out of memory (22 millions d'enregistrements à stocker en mémoire), pas postgresql lui même.


Marc.

Hors ligne

Pied de page des forums