banniere

Le portail francophone de la géomatique


Toujours pas inscrit ? Mot de passe oublié ?
Nom d'utilisateur    Mot de passe              Toujours pas inscrit ?   Mot de passe oubliĂ© ?

#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

vincentp
Participant actif
Lieu: DrĂŽme
Date d'inscription: 18 Jul 2006
Messages: 129
Site web

Re: [PostgreSQL/PostGIS] Creation d'index

Squid a écrit:

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

vincentp
Participant actif
Lieu: DrĂŽme
Date d'inscription: 18 Jul 2006
Messages: 129
Site web

Re: [PostgreSQL/PostGIS] Creation d'index

Squid a écrit:

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?


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é.


Squid a écrit:

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

 

Pied de page des forums

Copyright Association GeoRezo