#1 Wed 01 February 2012 10:04
- Squid
- Participant actif
- Date d'inscription: 2 Apr 2010
- Messages: 109
[PostgreSQL/PostGIS] Creation d'index
Bonjour,
toujours dans une recherche de gain de performances, je souhaite crĂ©er un ou des index pour la requĂȘte suivante :
Code:
CREATE OR REPLACE FUNCTION prof_bathy5(cle int) RETURNS SETOF int AS $$
DECLARE
rec record;
ma_var int;
BEGIN
FOR rec IN EXECUTE ('SELECT elevation FROM report_pt_simple pt, bathymetry bathy where gid='||cle||' group by elevation,bathy.geogr,pt.geogr,bathy.the_geom,pt.the_geom having ST_Distance(geography(ST_closestpoint(bathy.the_geom,pt.the_geom)),pt.geogr)=(SELECT min(ST_Distance(geography(ST_closestpoint(ba2.the_geom, pt2.the_geom)), pt2.geogr)) FROM report_pt_simple pt2, bathymetry ba2 where gid='||cle||') ') LOOP
ma_var:=rec.elevation;
RETURN NEXT ma_var;
END LOOP;
END;
$$ LANGUAGE plpgsql;
BEGIN;
SELECT fr.profondeur, pt.* FROM (SELECT prof_bathy5(gid) as profondeur, gid FROM report_pt_simple where gid between 1 and 200 )fr, report_pt_simple pt where pt.gid=fr.gid ;cette requĂȘte prend 13s pour 50 enregistrements et 4 min pour la totalitĂ© des enregistrements !
C'est pourquoi je souhaite créer des index.
J'ai utilisé la méthode suivante sans résultats significatif.
Pouvez vous m'indiquer sur quels champs faire mes index et si je dois appeler mes index dans mes requĂȘtes SELECT?
Merci
Hors ligne
#2 Wed 01 February 2012 11:24
Re: [PostgreSQL/PostGIS] Creation d'index
Bonjour,
toujours dans une recherche de gain de performances, je souhaite crĂ©er un ou des index pour la requĂȘte suivante :Code:
CREATE OR REPLACE FUNCTION prof_bathy5(cle int) RETURNS SETOF int AS $$ DECLARE rec record; ma_var int; BEGIN FOR rec IN EXECUTE ('SELECT elevation FROM report_pt_simple pt, bathymetry bathy where gid='||cle||' group by elevation,bathy.geogr,pt.geogr,bathy.the_geom,pt.the_geom having ST_Distance(geography(ST_closestpoint(bathy.the_geom,pt.the_geom)),pt.geogr)=(SELECT min(ST_Distance(geography(ST_closestpoint(ba2.the_geom, pt2.the_geom)), pt2.geogr)) FROM report_pt_simple pt2, bathymetry ba2 where gid='||cle||') ') LOOP ma_var:=rec.elevation; RETURN NEXT ma_var; END LOOP; END; $$ LANGUAGE plpgsql; BEGIN; SELECT fr.profondeur, pt.* FROM (SELECT prof_bathy5(gid) as profondeur, gid FROM report_pt_simple where gid between 1 and 200 )fr, report_pt_simple pt where pt.gid=fr.gid ;cette requĂȘte prend 13s pour 50 enregistrements et 4 min pour la totalitĂ© des enregistrements !
C'est pourquoi je souhaite créer des index.
J'ai utilisé la méthode suivante sans résultats significatif.
Pouvez vous m'indiquer sur quels champs faire mes index et si je dois appeler mes index dans mes requĂȘtes SELECT?
Merci
Bonjour,
Il faudrait déjà décorréler la partie plpgsql de la partie SQL à proprement parler.
Le plpgsql et les boucles, c'est particuliĂšrement peu rapide. Si on peut s'en passer complĂštement c'est encore mieux.
L'analyse de perf se fait ensuite sur la requete SQL pure, avec EXPLAIN pour identifier les points problématiques.
A vue de nez, vous n'avez aucune fonction spatiale qui peut utiliser les indexes, donc les ajouter ne va pas changer grand chose. Il faudrait regarder plus en détail mais souvent on peut remplacer du st_distance par du st_dwithin, ou avoir les deux, ce qui permet d'utiliser les indexes.
Il faut Ă©videmment un index sur le champ gid, mais si c'est une PK il doit y ĂȘtre dĂ©jĂ .
Ensuite si on lit tous les enregistrements d'une table, ajouter des indexes ne changera rien, l'optimisation se fait plutot sur le matériel de stockage et la mémoire dans ce cas.
J'espĂšre que ces quelques pistes vous aideront.
Hors ligne
#3 Wed 01 February 2012 17:31
- Squid
- Participant actif
- Date d'inscription: 2 Apr 2010
- Messages: 109
Re: [PostgreSQL/PostGIS] Creation d'index
Merci,
en tenant compte de vos conseils et en m'intĂ©ressant Ă l'exemple de ST_dwithin, je suis arrivĂ© Ă cette requĂȘte qui donne les mĂȘmes rĂ©sultats
Code:
SELECT mm.*
FROM
(SELECT DISTINCT ON (gt.gid) gt.gid, gt.dob_cm, gt.elevation elevation
FROM
(SELECT gid, dob_cm,elevation, h.the_geom geoba,s.the_geom geopt, s.geogr geogrpt FROM report_pt_simple s ,bathymetry h) gt
ORDER BY gt.gid, ST_Distance(geography(ST_closestpoint(geoba,geopt)),geogrpt)) mm;Je me rend compte que la sous requĂȘte
Code:
(SELECT gid, dob_cm,elevation, h.the_geom geoba,s.the_geom geopt, s.geogr geogrpt FROM report_pt_simple s ,bathymetry h)
est répétée autant de fois qu'il y a d'enregistrements. Comment mettre en variable le résultat d'un produit cartésien pour qu'il ne soit éxécuté qu'une fois?
D'autre part je n'arrive toujours pas Ă configurer mon serveur.
Merci.
Dernière modification par Squid (Wed 01 February 2012 17:31)
Hors ligne
#4 Wed 01 February 2012 18:22
Re: [PostgreSQL/PostGIS] Creation d'index
Merci,
en tenant compte de vos conseils et en m'intĂ©ressant Ă l'exemple de ST_dwithin, je suis arrivĂ© Ă cette requĂȘte qui donne les mĂȘmes rĂ©sultatsCode:
SELECT mm.* FROM (SELECT DISTINCT ON (gt.gid) gt.gid, gt.dob_cm, gt.elevation elevation FROM (SELECT gid, dob_cm,elevation, h.the_geom geoba,s.the_geom geopt, s.geogr geogrpt FROM report_pt_simple s ,bathymetry h) gt ORDER BY gt.gid, ST_Distance(geography(ST_closestpoint(geoba,geopt)),geogrpt)) mm;Je me rend compte que la sous requĂȘte
Code:
(SELECT gid, dob_cm,elevation, h.the_geom geoba,s.the_geom geopt, s.geogr geogrpt FROM report_pt_simple s ,bathymetry h)est répétée autant de fois qu'il y a d'enregistrements. Comment mettre en variable le résultat d'un produit cartésien pour qu'il ne soit éxécuté qu'une fois?
C'est surtout que cette sous requĂȘte fait une jointure complĂšte.
Mais il faudrait réécrire l'ensemble en passant la sous requĂȘte directement dans la requĂȘte principale. Elle n'a Ă priori aucune raison dâĂȘtre tel que c'est Ă©crit ici.
Maintenant si vous faite une requete avec un produit cartésien complet sur des tables volumineuses, sans filtre, et avec un order by, ce sera long de toutes façons. Mais pour avancer ensuite il faut connaitre la donnée et le but réel recherché.
D'autre part je n'arrive toujours pas Ă configurer mon serveur.
C'est encore un thÚme à part entiÚre, et qui dépend fortement de la typologie d'utilisation de la base de données, et du matériel sous jacent.
Hors ligne

