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 >

vendredi 10 octobre 2008

Prepare statements et insertion sur partitionnement de tables - Part III

Toujours sur l'exemple du poste précédent, on complique maintenant le jeu. On a ajouté maintenant la colonne répétition aux tables mesures_X qui décompte le nombre de fois où la valeur à insérer apparaît dans le fichier.

Pour chaque valeur lue dans le fichier values.txt

  • si la valeur à insérer est déjà présente en base alors on met à jour le champs répétition (UPDATE);
  • si la valeur n'est pas déjà présente alors on l'insère (INSERT).

Ce qui donne

#!/usr/bin/perl
use DBI;

$DB_name    = 'test';
$DB_user    = 'postgres';
$DB_pwd     = 'keizer';

$dbh = DBI->connect("dbi:Pg:dbname=$DB_name","$DB_user","$DB_pwd");

$sth0 = $dbh->prepare("set constraint_exclusion to on;select count(*) from mesure where value=?");
$sth1  = $dbh->prepare("set constraint_exclusion to on;insert into mesure(value) values (?)");
$sth2  = $dbh->prepare("set constraint_exclusion to on;update mesure set repetition=repetition+1 where value=?");


open FICHIER,"< values.txt" or  die "Le fichier n'existe pas !";

$iter=0;

while ($ligne = <FICHIER>){
        if (($iter%5000)==0){ print "$iter parsées\t";system "date '+%Y-%m-%d %H:%M:%S'";}

        $sth0->bind_param(1,$ligne);
        $sth0->execute();
        while ( ($count) = $sth0->fetchrow_array() ){
        if ($count==0){
                        $sth1->bind_param(1,$ligne);
                        $sth1->execute();
        }
        else{
                        $sth2->bind_param(1,$ligne);
                        $sth2->execute();
        }
       }
        $iter++;
}

close FICHIER;
$sth0->finish();
$sth1->finish();
$sth2->finish();
$dbh->disconnect();

A l'exécution, on aura

0 parsées       2008-10-10 17:57:53
5000 parsées    2008-10-10 17:58:07
10000 parsées   2008-10-10 17:58:20
15000 parsées   2008-10-10 17:58:33
20000 parsées   2008-10-10 17:58:47
25000 parsées   2008-10-10 17:59:00
30000 parsées   2008-10-10 17:59:14
35000 parsées   2008-10-10 17:59:28
40000 parsées   2008-10-10 17:59:42
45000 parsées   2008-10-10 17:59:58

Soit une moyenne de 14 secondes pour 50000 valeurs à parser soit 357 valeurs traitées par seconde sur une AMD 64 (sous réserver de la configuration du serveur).

On aura le schema de tables suivant

BEGIN;
CREATE TABLE mesure(value float,repetition integer default 0);

CREATE TABLE mesure_100000 ( check (value >= 0 and  value<100000) ) INHERITS (mesure);
CREATE TABLE mesure_200000 ( check (value >= 100000 and  value<200000)) INHERITS (mesure);
CREATE TABLE mesure_300000 ( check (value >= 200000 and  value<300000)) INHERITS (mesure);
CREATE TABLE mesure_400000 ( check (value >= 300000 and  value<400000)) INHERITS (mesure);
CREATE TABLE mesure_500000 (check (value >= 400000 and  value<500000) ) INHERITS (mesure);
CREATE TABLE mesure_600000 ( check (value >= 500000 and  value<600000)) INHERITS (mesure);
CREATE TABLE mesure_700000 ( check (value >= 600000 and  value<700000)) INHERITS (mesure);
CREATE TABLE mesure_800000 ( check (value >= 700000 and  value<800000)) INHERITS (mesure);
CREATE TABLE mesure_900000 ( check (value >= 800000 and  value<900000)) INHERITS (mesure);
CREATE TABLE mesure_1000000 (check (value >= 900000 and  value<1000000) ) INHERITS (mesure);
CREATE TABLE mesure_out (  check (value < 0 or  value>1000000)) INHERITS (mesure);

CREATE OR REPLACE RULE mesure_insert_100000 AS ON INSERT TO mesure WHERE ( NEW.value>=0 and NEW.value<100000) DO INSTEAD INSERT INTO mesure_100000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_200000 AS ON INSERT TO mesure WHERE ( NEW.value>=100000 and NEW.value<200000) DO INSTEAD INSERT INTO mesure_200000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_300000 AS ON INSERT TO mesure WHERE ( NEW.value>=200000 and NEW.value<300000) DO INSTEAD INSERT INTO mesure_300000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_400000 AS ON INSERT TO mesure WHERE ( NEW.value>=300000 and NEW.value<400000) DO INSTEAD INSERT INTO mesure_400000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_500000 AS ON INSERT TO mesure WHERE ( NEW.value>=400000 and NEW.value<500000) DO INSTEAD INSERT INTO mesure_500000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_600000 AS ON INSERT TO mesure WHERE ( NEW.value>=500000 and NEW.value<600000) DO INSTEAD INSERT INTO mesure_600000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_700000 AS ON INSERT TO mesure WHERE ( NEW.value>=600000 and NEW.value<700000) DO INSTEAD INSERT INTO mesure_700000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_800000 AS ON INSERT TO mesure WHERE ( NEW.value>=700000 and NEW.value<800000) DO INSTEAD INSERT INTO mesure_800000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_900000 AS ON INSERT TO mesure WHERE ( NEW.value>=800000 and NEW.value<900000) DO INSTEAD INSERT INTO mesure_900000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_1000000 AS ON INSERT TO mesure WHERE ( NEW.value>=900000 and NEW.value<1000000) DO INSTEAD INSERT INTO mesure_1000000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_out AS ON INSERT TO mesure WHERE ( NEW.value < 0 or  NEW.value>1000000) DO INSTEAD INSERT INTO mesure_out VALUES (NEW.value);

CREATE INDEX m_idx_100000 ON mesure_100000(value);
CREATE INDEX m_idx_200000 ON mesure_200000(value);
CREATE INDEX m_idx_300000 ON mesure_300000(value);
CREATE INDEX m_idx_400000 ON mesure_400000(value);
CREATE INDEX m_idx_500000 ON mesure_500000(value);
CREATE INDEX m_idx_600000 ON mesure_600000(value);
CREATE INDEX m_idx_700000 ON mesure_700000(value);
CREATE INDEX m_idx_800000 ON mesure_800000(value);
CREATE INDEX m_idx_900000 ON mesure_900000(value);
CREATE INDEX m_idx_1000000 ON mesure_1000000(value);
CREATE INDEX m_idx_out ON mesure_out(value);


CREATE VIEW mesure_all as 
SELECT * FROM mesure_100000
UNION ALL SELECT * FROM mesure_200000
UNION ALL SELECT * FROM mesure_300000
UNION ALL SELECT * FROM mesure_400000
UNION ALL SELECT * FROM mesure_500000
UNION ALL SELECT * FROM mesure_600000
UNION ALL SELECT * FROM mesure_700000
UNION ALL SELECT * FROM mesure_800000
UNION ALL SELECT * FROM mesure_900000
UNION ALL SELECT * FROM mesure_1000000
UNION ALL SELECT * FROM mesure_out;

END;

On a rappelons le 50 000 lignes dans le fichiers values.txt confirmée par la commande suivante:

test=# select count(a.value),a.repetition from mesure a group by 2;;
 count | repetition 
-------+------------
     1 |          3
    67 |          2
  1935 |          1
 45925 |          0
(4 lignes)
Soit 45925 valeurs qui ne se répètent pas, 1935 qui se répètent une fois etc...
test=# select 45925+1935*2+67*3+4;
 ?column? 
----------
    50000
(1 ligne)
ou de manière basique
test=# select sum(foo.decompte) from (select (repetition+1)*count(*) as decompte from mesure group by repetition ) as foo;
  sum  
-------
 50000
(1 ligne)

jeudi 9 octobre 2008

Prepare statements et insertion sur partitionnement de tables - Part II

Par rapport au poste précédent, on va cette fois ci répartir les données dans la table mesure par pas de 100 000.

On commence par tout télécharger sur le site et on décompresse le fichier
[jdtecher@jdtecher momo]$ wget http://www.davidgis.fr/download/mesure.zip;unzip mesure.zip;cd mesure
--19:51:00--  http://www.davidgis.fr/download/mesure.zip
           => `mesure.zip'
Résolution de www.davidgis.fr... 82.236.232.184
Connexion vers www.davidgis.fr|82.236.232.184|:80...connecté.
requête HTTP transmise, en attente de la réponse...200 OK
Longueur: 424097 (414K) [application/zip]

100%[=============================================================================================================>] 424097       107.08K/s    ETA 00:00

19:51:04 (105.94 KB/s) - « mesure.zip » sauvegardé [424097/424097]

Archive:  mesure.zip
   creating: mesure/
  inflating: mesure/mesures_schema.sql  
  inflating: mesure/mesures_insert.sql  
  inflating: mesure/mesures_exec.sql 

Voici la structure des diverses tables

BEGIN;
CREATE TABLE mesure(value float);

CREATE TABLE mesure_100000 ( check (value >= 0 and  value<100000) ) INHERITS (mesure);
CREATE TABLE mesure_200000 ( check (value >= 100000 and  value<200000)) INHERITS (mesure);
CREATE TABLE mesure_300000 ( check (value >= 200000 and  value<300000)) INHERITS (mesure);
CREATE TABLE mesure_400000 ( check (value >= 300000 and  value<400000)) INHERITS (mesure);
CREATE TABLE mesure_500000 (check (value >= 400000 and  value<500000) ) INHERITS (mesure);
CREATE TABLE mesure_600000 ( check (value >= 500000 and  value<600000)) INHERITS (mesure);
CREATE TABLE mesure_700000 ( check (value >= 600000 and  value<700000)) INHERITS (mesure);
CREATE TABLE mesure_800000 ( check (value >= 700000 and  value<800000)) INHERITS (mesure);
CREATE TABLE mesure_900000 ( check (value >= 800000 and  value<900000)) INHERITS (mesure);
CREATE TABLE mesure_1000000 (check (value >= 900000 and  value<1000000) ) INHERITS (mesure);
CREATE TABLE mesure_out (  check (value < 0 or  value>1000000)) INHERITS (mesure);

CREATE OR REPLACE RULE mesure_insert_100000 AS ON INSERT TO mesure WHERE ( value>=0 and value<100000) DO INSTEAD INSERT INTO mesure_100000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_200000 AS ON INSERT TO mesure WHERE ( value>=100000 and value<200000) DO INSTEAD INSERT INTO mesure_200000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_300000 AS ON INSERT TO mesure WHERE ( value>=200000 and value<300000) DO INSTEAD INSERT INTO mesure_300000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_400000 AS ON INSERT TO mesure WHERE ( value>=300000 and value<400000) DO INSTEAD INSERT INTO mesure_400000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_500000 AS ON INSERT TO mesure WHERE ( value>=400000 and value<500000) DO INSTEAD INSERT INTO mesure_500000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_600000 AS ON INSERT TO mesure WHERE ( value>=500000 and value<600000) DO INSTEAD INSERT INTO mesure_600000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_700000 AS ON INSERT TO mesure WHERE ( value>=600000 and value<700000) DO INSTEAD INSERT INTO mesure_700000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_800000 AS ON INSERT TO mesure WHERE ( value>=700000 and value<800000) DO INSTEAD INSERT INTO mesure_800000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_900000 AS ON INSERT TO mesure WHERE ( value>=800000 and value<900000) DO INSTEAD INSERT INTO mesure_900000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_1000000 AS ON INSERT TO mesure WHERE ( value>=900000 and value<1000000) DO INSTEAD INSERT INTO mesure_1000000 VALUES (NEW.value);
CREATE OR REPLACE RULE mesure_insert_out AS ON INSERT TO mesure WHERE ( value < 0 or  value>1000000) DO INSTEAD INSERT INTO mesure_out VALUES (NEW.value);

CREATE VIEW mesure_all as 
SELECT * FROM mesure_100000
UNION ALL SELECT * FROM mesure_200000
UNION ALL SELECT * FROM mesure_300000
UNION ALL SELECT * FROM mesure_400000
UNION ALL SELECT * FROM mesure_500000
UNION ALL SELECT * FROM mesure_600000
UNION ALL SELECT * FROM mesure_700000
UNION ALL SELECT * FROM mesure_800000
UNION ALL SELECT * FROM mesure_900000
UNION ALL SELECT * FROM mesure_1000000
UNION ALL SELECT * FROM mesure_out;

END;
Les deux fichiers ont le contenu suivant avec 50 000 valeurs aléataoires identiques dans les deux fichiers
  • pour mesures_insert.sql
    begin;
    insert into mesure values (1061095);
    insert into mesure values (584444);
    insert into mesure values (1117347);
    insert into mesure values (634985);
    insert into mesure values (249222);
    .... .....
    ... ....
    ... ....
    end;
    
  • pour mesures_exec.sql
    begin;
    prepare insert_mesure(real) as insert into mesure values ($1);
    SET constraint_exclusion = on;
    execute insert_mesure(1061095);
    execute insert_mesure(584444);
    execute insert_mesure(1117347);
    execute insert_mesure(634985);
    execute insert_mesure(249222);
    .... .....
    ... ....
    ... ....
    end;
    

Maintenant on va tester l'import pour 50 000 valeurs aléatoires pour le prepare/execute et l'insertion usuelle

[jdtecher@jdtecher mesure]$ for mode in insert exec;do dropdb test > /dev/null;createdb test > /dev/null ;\
psql -d test -f mesures_schema.sql  > /dev/null;echo " mode = $mode";date;psql -d test -f mesures_$mode.sql > /dev/null ;\
date;done
 mode = insert
jeu oct  9 19:51:38 CEST 2008
jeu oct  9 19:52:14 CEST 2008
 mode = exec
jeu oct  9 19:52:15 CEST 2008
jeu oct  9 19:52:25 CEST 2008
Le rapport est quand même remarquable. Soit un facteur de 3.5 sur une machine AMD64 qui a servit de base de Test pour un serveur PostgreSQL 8.1

Exemple en Perl DBI

On a maintenant un fichier values.txt qui contient les diverses valeurs déjà présentes. Nous allons utilisé perl pour lire les valeurs et les insérer grâce à DBI.

On aura par exemple le script suivant

#!/usr/bin/perl
use DBI;

$DB_name    = 'test';
$DB_user    = 'postgres';
$DB_pwd     = '****';

$dbh = DBI->connect("dbi:Pg:dbname=$DB_name","$DB_user","$DB_pwd");

print "\nConnection error: $DBI::errstr\n\n";

$sth  = $dbh->prepare("insert into mesure values(?)");


open FICHIER,"< values.txt" or  die "Le fichier n'existe pas !";

while ($ligne = ){
        $sth->bind_param(1,$ligne);
        $sth->execute();
}

close FICHIER;
$sth->finish();
$dbh->disconnect();
Pour le lancer
PGHOST=localhost ./pg_exec.pl

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.