2 pièce(s) jointe(s)
[PostGreSQL][Optimisation] Requête des dernières saisies
Bonjour,
Je pêche sur l'optimisation d'une de mes requêtes. Celle-ci s'execute en 35secondes. C'es beaucoup trop. Je ne parviens pas à l'améliorer.
Vous trouverez une capture d'écran du MPD en pièce jointe.
Informations sur les tables concernées :
Citation:
te_circulationcondition_con : Stocke les conditions de circulation, 4 valeurs existent dans cette table (nickel, neige, verglas, impraticable).
te_troncon_tro : Stocke les différents tronçons de route. 68 valeurs existent dans cette table.
te_direction_dir : ne pas en tenir compte, cette table va être supprimée et la jointure aussi.
ts_utilisateur_uti : Stocke les différents utilisateurs du système. 1 valeur existe pour le moment dans cette table. En production, il devrait y en avoir 8.
tj_etat_eta : Stocke l'état de la route à l'instant t. On note donc la clef du troncon(colonne tro_id), la clef de l'utilisateur (colonne uti_id)qui fait la saisie, l'horodatage de la saisie (colonne eta_ins), la condition de conduite relevée (colonne con_id). Chaque année il y a (troncon * jour) saisies. Là je fais de petits tests avec 9000 valeurs de tests et je suis déjà à 35 secondes !
Je veux créer une vue qui ne contient que la dernière condition de conduite relevée pour chaque tronçon. Donc pour le moment, je crée la vue. Mais ce qui m'inquiète est que la requête met 35 secondes à s'exécuter.
Voici la requête que j'ai construite :
Code:
1 2 3 4 5 6 7 8 9 10 11 12
| select eta.eta_id, eta.eta_ins,eta.tro_id,eta.dir_id,eta.con_id,
tro.tro_lib,tro.tro_ord,tro.tro_zone_sensible,tro.tro_moins,tro.tro_plus,
con.con_ci,con.con_couleur
from tj_etat_eta eta
inner join tj_etat_eta eta2 on eta.tro_id = eta2.tro_id
inner join te_troncon_tro tro on tro.tro_id = eta.tro_id
inner join te_conditioncirculation_con con on eta.con_id = con.con_id
group by eta.eta_id, eta.eta_ins,eta.tro_id,eta.dir_id,eta.con_id,
tro.tro_lib,tro.tro_ord,tro.tro_zone_sensible,tro.tro_moins,tro.tro_plus,
con.con_ci,con.con_couleur
having max(eta2.eta_ins) = eta.eta_ins
order by eta.tro_id, eta.eta_id |
Voici ce que me retourne l'explain plan :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
|
GroupAggregate (cost=463675.41..520191.21 rows=1130316 width=195)
Filter: (max((eta_ins)::timestamp without time zone) = (eta_ins)::timestamp without time zone)
-> Sort (cost=463675.41..466501.20 rows=1130316 width=195)
Sort Key: eta.tro_id, eta.eta_id, eta.eta_ins, eta.dir_id, eta.con_id, tro.tro_lib, tro.tro_ord, tro.tro_zone_sensible, tro.tro_moins, tro.tro_plus, con.con_ci, con.con_couleur
-> Hash Join (cost=314.99..13916.28 rows=1130316 width=195)
Hash Cond: ((eta.tro_id)::integer = (eta2.tro_id)::integer)
-> Hash Join (cost=45.65..445.88 rows=8726 width=191)
Hash Cond: ((eta.tro_id)::integer = tro.tro_id)
-> Hash Join (cost=23.50..303.74 rows=8726 width=88)
Hash Cond: ((eta.con_id)::integer = con.con_id)
-> Seq Scan on tj_etat_eta eta (cost=0.00..160.26 rows=8726 width=24)
-> Hash (cost=16.00..16.00 rows=600 width=68)
-> Seq Scan on te_conditioncirculation_con con (cost=0.00..16.00 rows=600 width=68)
-> Hash (cost=15.40..15.40 rows=540 width=103)
-> Seq Scan on te_troncon_tro tro (cost=0.00..15.40 rows=540 width=103)
-> Hash (cost=160.26..160.26 rows=8726 width=12)
-> Seq Scan on tj_etat_eta eta2 (cost=0.00..160.26 rows=8726 width=12) |
Petite précision qui a son importance : Le moteur de base de données est PostGreSQL. Par conséquent il existe un index automatiquement créé pour chaque colonne d'une clef étrangère. L'index i1_eta de la table tj_etat_eta porte sur la colonne eta_ins
Seconde précision : Le MPD n'est pas figé.
Comment améliorer le temps d'exécution de ma requête ?
Sachant que la requête va être transformée en vue, ce temps de calcul est-il si problématique ?