Vous n'êtes pas identifié(e).
Pages : 1
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
Il estime que id_lot IN (167582,167586) va ramener 22064588 enregistrements.
Il a faux ?
Marc.
Hors ligne
Et il y a combien de lignes dans cette table ?
Guillaume.
Hors ligne
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
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
Pages : 1