Bonjour,
je suis actuellement en train de travailler sur la réalisation de cartes statistiques de population sur un département.
Le but de l'operation est de generer un quadrillage (avec des carrés de 1000m²) du departement, afin d'y generer une matrice.
J'obtiens 7760 carrés pour ce departement.
le but maintenant est de trouver les intersections de chaque carré avec les communes (472 communes au total).
les tables communes et quadrillages de postgres sont les suivantes.
CREATE TABLE commune
(
gid serial NOT NULL,
id_bdcarto float8,
population float8,
the_geom geometry,
CONSTRAINT commune_pkey PRIMARY KEY (gid),
CONSTRAINT enforce_dims_the_geom CHECK (ndims(the_geom) = 2),
CONSTRAINT enforce_geotype_the_geom CHECK (geometrytype(the_geom) = 'MULTIPOLYGON'::text OR the_geom IS NULL),
CONSTRAINT enforce_srid_the_geom CHECK (srid(the_geom) = -1)
)
WITHOUT OIDS;
ALTER TABLE commune OWNER TO postgres;
-- Index: idx2_commune
-- DROP INDEX idx2_commune;
CREATE INDEX idx2_commune
ON commune
USING gist
(the_geom);
-- Index: idx_commune
-- DROP INDEX idx_commune;
CREATE INDEX idx_commune
ON commune
USING btree
(gid);
et quadrillage
CREATE TABLE quadrillage
(
id serial NOT NULL,
qrows int4,
qcols int4,
geom geometry,
CONSTRAINT quadrillage_pkey PRIMARY KEY (id),
CONSTRAINT enforce_dims_geom CHECK (ndims(geom) = 2),
CONSTRAINT enforce_srid_geom CHECK (srid(geom) = -1)
)
WITHOUT OIDS;
ALTER TABLE quadrillage OWNER TO sig;
-- Index: idx2_quadrillage
-- DROP INDEX idx2_quadrillage;
CREATE INDEX idx2_quadrillage
ON quadrillage
USING gist
(geom);
-- Index: idx_quadrillage
-- DROP INDEX idx_quadrillage;
CREATE UNIQUE INDEX idx_quadrillage
ON quadrillage
USING btree
(id);
Mon code est le suivant:
$sql = "select * from quadrillage order by qrows desc, qcols asc ";
$res = pg_query($sql);
$nb =0;
$tabTimeR = array();
$matrice = "Z = [";
while($req = pg_fetch_object($res))
{
$id = $req->id;
$cols = $req->qcols;
$rows = $req->qrows;
$temps_debut_r = microtime_float();
$sql2 = "select b.population as population from quadrillage as a, commune as b where Intersects(a.geom,b.the_geom) and a.id = ".$id;
$res2 = pg_query($sql2);
$temps_fin_r = microtime_float();
array_push($tabTimeR,round($temps_fin_r - $temps_debut_r, 4));
$cpt = 0;
$total = 0;
while($req2 = pg_fetch_object($res2))
{
$intervention = $req2->population;
if($intervention > $tripleMoyenne)
$intervention = $tripleMoyenne;
$total += $intervention;
$cpt++;
}
if($cpt == 0)
$moyenne = 0;
else $moyenne = $total/$cpt;
if($cols == 0)
$matrice .= "[".$moyenne;
if($cols == $maxcols)
{
$nb++;
if($nb == $nb_rows)
$matrice .= ",".$moyenne."]";
else $matrice .= ",".$moyenne."],";
}
if($cols != 0 && $cols != $maxcols)
$matrice .= ",".$moyenne;
$nb++;
echo "\rNb requete: ".$nb."\t";
}
$matrice .="]";
$temps_fin = microtime_float();
echo "\nTemps d\'execution du script : ".round($temps_fin - $temps_debut, 4)."\nRequete plus courte :".min($tabTimeR)."\nrequete plus longue :".max($tabTimeR)."\n";
mon cpu : AMD Athlon(tm) 64 X2 Dual Core Processor 4400+
ma Ram : 2Go
J'obtiens comme resultat ceci:
Nb requete: 7760
Temps d\'execution du script : 88.212 s.
Requete plus courte :0.009 s.
requete plus longue :0.0312 s.
Le but est de faire de la generation de carte instantanée, mais mes temps de génération sont peu convainquant pour les visiteurs.
J'aurais voulu savoir donc, si j'avais fait les bons choix dans la création de mes index suivants les requetes effectuées.(des vacuum full analyze ont été executé en amont).
Cela revient à environ 93 requetes / s. est-ce que je peux faire plus rapide ?
je gagne en rapidité à partir du moment où j'augmente les carrés de mon quadrillage , mais la matrice devient plus petite, et je perds en qualité du résultat.
en esperant avoir été assez clair.
ps : un apercu de la réalisation pour y voir plus clair:
http://guibsou.free.fr/stats/image1.png
http://guibsou.free.fr/stats/pop.png
merci.
Partager