Le blog de Jean David TECHER, un Réunionnais à Saint-Priest/Lyon

Aller au contenu | Aller au menu | Aller à la recherche


< 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 >

jeudi 9 octobre 2008

Prepare statements et insertion sur partitionnement de tables - Part I

On a la base ayant la structure suivante

\timing

BEGIN;
CREATE TABLE mesure(value float);

CREATE TABLE mesure_10 ( check (value >= 0 and  value<10) ) INHERITS (mesure);
CREATE TABLE mesure_20 ( check (value >= 10 and  value<20)) INHERITS (mesure);
CREATE TABLE mesure_30 ( check (value >= 20 and  value<30)) INHERITS (mesure);
CREATE TABLE mesure_40 ( check (value >= 30 and  value<40)) INHERITS (mesure);
CREATE TABLE mesure_50 (check (value >= 40 and  value<50) ) INHERITS (mesure);
CREATE TABLE mesure_60 ( check (value >= 50 and  value<60)) INHERITS (mesure);
CREATE TABLE mesure_70 ( check (value >= 60 and  value<70)) INHERITS (mesure);
CREATE TABLE mesure_80 ( check (value >= 70 and  value<80)) INHERITS (mesure);
CREATE TABLE mesure_90 ( check (value >= 80 and  value<90)) INHERITS (mesure);
CREATE TABLE mesure_100 (check (value >= 90 and  value<100) ) INHERITS (mesure);
CREATE TABLE mesure_out (  check (value < 0 or  value>100)) INHERITS (mesure);

CREATE OR REPLACE RULE mesure_insert_10 AS ON INSERT TO mesure WHERE ( value>=0 and value<10) DO INSTEAD INSERT INTO mesure_10 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_20 AS ON INSERT TO mesure WHERE ( value>=10 and value<20) DO INSTEAD INSERT INTO mesure_20 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_30 AS ON INSERT TO mesure WHERE ( value>=20 and value<30) DO INSTEAD INSERT INTO mesure_30 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_40 AS ON INSERT TO mesure WHERE ( value>=30 and value<40) DO INSTEAD INSERT INTO mesure_40 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_50 AS ON INSERT TO mesure WHERE ( value>=40 and value<50) DO INSTEAD INSERT INTO mesure_50 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_60 AS ON INSERT TO mesure WHERE ( value>=50 and value<60) DO INSTEAD INSERT INTO mesure_60 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_70 AS ON INSERT TO mesure WHERE ( value>=60 and value<70) DO INSTEAD INSERT INTO mesure_70 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_80 AS ON INSERT TO mesure WHERE ( value>=70 and value<80) DO INSTEAD INSERT INTO mesure_80 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_90 AS ON INSERT TO mesure WHERE ( value>=80 and value<90) DO INSTEAD INSERT INTO mesure_90 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_100 AS ON INSERT TO mesure WHERE ( value>=90 and value<100) DO INSTEAD INSERT INTO mesure_100 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_out AS ON INSERT TO mesure WHERE ( value < 0 or  value>100) DO INSTEAD INSERT INTO mesure_out VALUES (NEW.value);

CREATE VIEW mesure_all as 
SELECT * FROM mesure_10
UNION ALL SELECT * FROM mesure_20
UNION ALL SELECT * FROM mesure_30
UNION ALL SELECT * FROM mesure_40
UNION ALL SELECT * FROM mesure_50
UNION ALL SELECT * FROM mesure_60
UNION ALL SELECT * FROM mesure_70
UNION ALL SELECT * FROM mesure_80
UNION ALL SELECT * FROM mesure_90
UNION ALL SELECT * FROM mesure_100
UNION ALL SELECT * FROM mesure_out;

END;

On va lancer deux insertions massives. La première avant un prepare et execute et la seconde par des insert habituelles

Avec prepare/execute

On a le fichier avec le contenu suivant

\timing
begin;
prepare insert_mesure(real) as insert into mesure values ($1);
SET constraint_exclusion = on;
execute insert_mesure(1);
execute insert_mesure(2);
execute insert_mesure(3);
execute insert_mesure(4);
execute insert_mesure(5);
execute insert_mesure(6);
execute insert_mesure(7);
execute insert_mesure(8);
execute insert_mesure(9);
execute insert_mesure(10);
....   ....
....  ....
execute insert_mesure(999994);
execute insert_mesure(999995);
execute insert_mesure(999996);
execute insert_mesure(999997);
execute insert_mesure(999998);
execute insert_mesure(999999);
execute insert_mesure(1000000);
end;

On crée la base. Puis on charge la structure de la base et on mesure le temps mis pour charger les 1 000 000 de valeurs à insérer

 dropdb test;createdb test;psql -d test -f test.sql;date;psql -d test -f values.sql > /dev/null ;date

On a l'estimation suivante

jeu oct  9 15:47:23 CEST 2008
jeu oct  9 15:50:56 CEST 2008

Soit 3 minutes et 33 secondes

avec des insertions usuelles

Cetet fois-ci, le contenu du fichier est

\timing
BEGIN;
INSERT INTO mesure VALUES (1);
INSERT INTO mesure VALUES (2);
INSERT INTO mesure VALUES (3);
INSERT INTO mesure VALUES (4);
INSERT INTO mesure VALUES (5);
INSERT INTO mesure VALUES (6);
... ....
... ...
INSERT INTO mesure VALUES (999998);
INSERT INTO mesure VALUES (999999);
INSERT INTO mesure VALUES (1000000);
END;
On rejoue les mêmes commandes
dropdb test;createdb test;psql -d test -f test.sql;date;psql -d test -f values_insert.sql > /dev/null ;date

On a

jeu oct  9 15:56:05 CEST 2008
jeu oct  9 16:09:06 CEST 2008

Soit 13 minutes et 1 seconde.

Excusion de contraintes

Jouons avec constraint_exclusion. On a alors
test=# set constraint_exclusion =on;
SET
test=# explain analyze select * from mesure where value >88 and value<2015;
                                                            QUERY PLAN                                                             
-----------------------------------------------------------------------------------------------------------------------------------
 Result  (cost=0.00..20406.81 rows=1459 width=8) (actual time=0.021..575.274 rows=1926 loops=1)
   ->  Append  (cost=0.00..20406.81 rows=1459 width=8) (actual time=0.019..574.944 rows=1926 loops=1)
         ->  Seq Scan on mesure  (cost=0.00..1.01 rows=1 width=8) (actual time=0.019..0.019 rows=1 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_90 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.015 rows=1 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_100 mesure  (cost=0.00..1.15 rows=10 width=8) (actual time=0.010..0.014 rows=10 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_out mesure  (cost=0.00..20403.50 rows=1447 width=8) (actual time=0.011..574.667 rows=1914 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
 Total runtime: 575.480 ms
(11 lignes)

test=# set constraint_exclusion =off;
SET
test=# explain analyze select * from mesure where value >88 and value<2015;
                                                            QUERY PLAN                                                             
-----------------------------------------------------------------------------------------------------------------------------------
 Result  (cost=0.00..20416.00 rows=1467 width=8) (actual time=0.018..589.760 rows=1926 loops=1)
   ->  Append  (cost=0.00..20416.00 rows=1467 width=8) (actual time=0.017..589.458 rows=1926 loops=1)
         ->  Seq Scan on mesure  (cost=0.00..1.01 rows=1 width=8) (actual time=0.017..0.018 rows=1 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_10 mesure  (cost=0.00..1.14 rows=1 width=8) (actual time=0.013..0.013 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_20 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.015..0.015 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_30 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.013..0.013 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_40 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_50 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_60 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_70 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_80 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=0 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_90 mesure  (cost=0.00..1.15 rows=1 width=8) (actual time=0.014..0.014 rows=1 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_100 mesure  (cost=0.00..1.15 rows=10 width=8) (actual time=0.011..0.016 rows=10 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
         ->  Seq Scan on mesure_out mesure  (cost=0.00..20403.50 rows=1447 width=8) (actual time=0.013..589.051 rows=1914 loops=1)
               Filter: ((value > 88::double precision) AND (value < 2015::double precision))
 Total runtime: 589.990 ms

Arrivée de la nouvelle FreeBox HD à Antibes

Ca y est, la FreeBox HD (que Fabrice avait commandé) est arrivée à l'appartement d'Antibes avant-hier. Petite par rapport à la version V4 et vraiment bien stylisé.

Du coup, meilleur débit pour aller sur internet etc...J'en au profité pour installer le matos qui va sur la télé pour regarde la télé. Notamment la chaine Mangas où passait un épisode de Cobra.

Ca fait bizarre par rapport à la V4 de ne plus avoir à tirer de fil entre le boitier de la Freebox et celui de la TV.

[PostGIS] Liens les plus consultés pour la doc sur PostGIS (journée du mercredi 2008-10-08)

Ma doc sur PostGIS a beau ne pas avoir été mise à jour depuis un bon moment, celà fait plaisir de voir ce genre de statistiques. Ces dernières concernent la journée du mercredi 8 octobre 2008.

www_log=# select distinct count(ip_addr) as "Nombre de consultation",data as "Intitulé",link as "Lien"from analyze_log 
join postgis_doc_ref on (link=record) group by 2,3 order by 1 desc;


 Nombre de consultation |                                  Intitulé                                   |                 Lien                 
------------------------+-----------------------------------------------------------------------------+--------------------------------------
                     19 | Annexe I. Mémento sur les commandes SQL de PostgreSQL                       | /documentation/win32/html/api.html
                     18 | Guide de l'utilisateur de PostgreSQL/PostGIS                                | /documentation/win32/html/index.html
                     15 | Annexe J. Mémento sur les commandes internes de psql                        | /documentation/win32/html/apj.html
                     14 | Chapitre 3. Installation sous Ubuntu Edgy Eft                               | /documentation/win32/html/ch03.html
                     13 | Annexe B. Créer un modèle de base de données PostgreSQL contenant les       | /documentation/win32/html/apb.html
                     13 | Avant-propos                                                                | /documentation/win32/html/pr01.html
                     12 | Annexe C. Dblink: interroger plusieurs serveurs PostgreSQL distants         | /documentation/win32/html/apc.html
                     12 | Chapitre 2. Compilation et Installation                                     | /documentation/win32/html/ch02.html
                     12 | PostgreSQL - configuration et administration minimale                       | /documentation/win32/html/pt03.html
                     11 | Annexe H. Foire Aux Questions                                               | /documentation/win32/html/aph.html
                     11 | PostGIS                                                                     | /documentation/win32/html/pt04.html
                     10 | Annexe D. Pouvoir faire des sauvegardes des bases locales ou distantes d'un | /documentation/win32/html/apd.html
                     10 | Chapitre 1. Pré-requis                                                      | /documentation/win32/html/ch01.html
                     10 | Chapitre 6. Etudes de cas                                                   | /documentation/win32/html/ch06.html
                     10 | Chapitre 9. MapServer: faire une image avec zones réactives                 | /documentation/win32/html/ch09.html
                     10 | Installation sous GNU/Linux, Ubuntu Edgy Eft                                | /documentation/win32/html/pt02.html
                      9 | Chapitre 7. PostGIS et les languages                                        | /documentation/win32/html/ch07.html
                      8 | Annexe A. PgRouting pour le calcul d'itinéraire                             | /documentation/win32/html/apa.html
                      8 | Annexe F. Connaître l'espace disque occupé par les données (dbsize)         | /documentation/win32/html/apf.html
                      7 | Annexe G. PostgreSQL et Stunnel                                             | /documentation/win32/html/apg.html
                      7 | Annexe K. Suivi de PostGIS                                                  | /documentation/win32/html/apk.html
                      6 | Annexe L. PhpMapScript                                                      | /documentation/win32/html/apl.html
                      6 | Notes à l'intention des utilisateurs                                        | /documentation/win32/html/pr02.html
                      5 | Annexe M. Auteurs et contributeurs de PostGIS                               | /documentation/win32/html/apm.html
                      5 | Installation sous Windows                                                   | /documentation/win32/html/pt01.html
                      5 | Notes sur les annexes                                                       | /documentation/win32/html/pr03.html
                      4 | Annexes                                                                     | /documentation/win32/html/pt05.html
                      4 | Bibliographie                                                               | /documentation/win32/html/bi01.html
                      4 | Chapitre 8. Conclusion                                                      | /documentation/win32/html/ch08.html
(29 lignes)
Le petit plus à celà, on ajoute
  • concernant pgRouting, j'ai compté 11 téléchargements;
  • 10 consultations au gros pavé au PDF de ma doc.

Ca fait plaisir de voir que celà reste un must en dépit de son ancienneté . Promis quand le temps me le permettra, je remettrais à jour ma doc !

mardi 7 octobre 2008

[pgday 2008] Résumé de la journée pgday sur Toulouse du samedi 4 octobre 2008.

Thomas Petazzoni qui a filmé les conférences de cette journée propose un aperçu des faits marquants sur ce billet de son blog.

Le moins que l'on puisse dire c'est que PostGIS a souvent été mis à l'honneur dans au moins deux conférences : une par camptocamp et l'autre par Makina Corpus. Je vous laisse le soin d'aller lire son billet pour de plus amples informations.