Re: Partitionement

From: Pierre BOIZOT <pierre(dot)boizot(at)gmail(dot)com>
To: Guillaume Lelarge <guillaume(at)lelarge(dot)info>
Cc: PG-Mail-liste <pgsql-fr-generale(at)postgresql(dot)org>
Subject: Re: Partitionement
Date: 2013-10-06 15:37:26
Message-ID: CANxSh5xigxdu_4G_oOoiG7xZHtrVzOAXi1vxQ-EqtVaKxFUFFQ@mail.gmail.com
Views: Whole Thread | Raw Message | Download mbox | Resend email
Thread:
Lists: pgsql-fr-generale

Hello,

J'ai fait le petit test suivant :

Creation d'une table sales avec 4 partitions et deux critéres de
partitionnement.
un étant une date et l'autre un code.

Il s'avere que l'écriture de la clause CHECK est importante ....

CREATE TABLE sales_part1
(CHECK (org = 6 and temps between to_date('20101001'::text,
'yyyymmdd'::text) and to_date('20131001'::text, 'yyyymmdd'::text)) )
INHERITS (sales);

transformé en :
test=# \d+ sales_part1
Table "public.sales_part1"
Column | Type | Modifiers | Storage | Description
--------+-----------------------------+-----------+----------+-------------
org | integer | | plain |
temps | timestamp without time zone | | plain |
name | character varying(10) | | extended |
Check constraints:
"sales_part1_check" CHECK (org = 6 AND temps >=
to_date('20101001'::text, 'yyyymmdd'::text) AND temps <=
to_date('20131001'::text, 'yyyymmdd'::text))
Inherits: sales
Has OIDs: no

​fait que la requete suivante parcourt toutes les partitions.

​explain analyze select * from sales where temps >= date '20131101' and
temps <= date '20141001';
QUERY
PLAN
-------------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..103.73 rows=21 width=50) (actual time=0.082..0.296
rows=5 loops=1)
-> Append (cost=0.00..103.73 rows=21 width=50) (actual
time=0.067..0.216 rows=5 loops=1)
-> Seq Scan on sales (cost=0.00..2.53 rows=1 width=50) (actual
time=0.019..0.019 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on sales_part1 sales (cost=0.00..25.30 rows=5
width=50) (actual time=0.011..0.011 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on sales_part2 sales (cost=0.00..25.30 rows=5
width=50) (actual time=0.009..0.023 rows=2 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on sales_part3 sales (cost=0.00..25.30 rows=5
width=50) (actual time=0.024..0.024 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on sales_part4 sales (cost=0.00..25.30 rows=5
width=50) (actual time=0.013..0.034 rows=3 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
Total runtime: 0.410 ms​

​alors que si la contrainte est écrite comme ci-dessous :
​CREATE TABLE ventes_part1
(CHECK ( (temps >= date '20101001' and temps <= date '20131001')
and org=6 ) )
INHERITS (ventes);​

​transformé en :
d+
ventes_part1

Table "public.ventes_part1"
Column | Type | Modifiers | Storage | Description
--------+-----------------------------+-----------+----------+-------------
org | integer | | plain |
temps | timestamp without time zone | | plain |
name | character varying(10) | | extended |
Check constraints:
"ventes_part1_check" CHECK (temps >= '2010-10-01'::date AND temps <=
'2013-10-01'::date AND org = 6)
Inherits: ventes
Has OIDs: no​

​la meme requete ne parcourera que deux partitions :-)​

​test=# explain analyse select * from ventes where temps >= date
'20131101' and temps <= date '20141001';
QUERY
PLAN
---------------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..53.13 rows=11 width=50) (actual time=0.056..0.169
rows=5 loops=1)
-> Append (cost=0.00..53.13 rows=11 width=50) (actual
time=0.046..0.120 rows=5 loops=1)
-> Seq Scan on ventes (cost=0.00..2.53 rows=1 width=50) (actual
time=0.023..0.023 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on ventes_part2 ventes (cost=0.00..25.30 rows=5
width=50) (actual time=0.011..0.021 rows=2 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
-> Seq Scan on ventes_part4 ventes (cost=0.00..25.30 rows=5
width=50) (actual time=0.009..0.022 rows=3 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date))
Total runtime: 0.235 ms
(9 rows)

si on ajoute un critere de filtre supplémentaire à la clause where .
on retrouve le meme comportement sur le parcours des partitions.

Parcours d'une partition
test=# explain analyse select * from ventes where temps >= date '20131101'
and temps <= date '20141001' and org=7;
QUERY
PLAN
---------------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..30.64 rows=2 width=50) (actual time=0.028..0.069
rows=3 loops=1)
-> Append (cost=0.00..30.64 rows=2 width=50) (actual time=0.022..0.048
rows=3 loops=1)
-> Seq Scan on ventes (cost=0.00..2.79 rows=1 width=50) (actual
time=0.009..0.009 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date) AND (org = 7))
-> Seq Scan on ventes_part4 ventes (cost=0.00..27.85 rows=1
width=50) (actual time=0.005..0.014 rows=3 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date) AND (org = 7))
Total runtime: 0.108 ms
(7 rows)

Parcours de deux partitions.
test=# explain analyse select * from sales where temps >= date '20131101'
and temps <= date '20141001' and org=7;
QUERY
PLAN
-------------------------------------------------------------------------------------------------------------------------
Result (cost=0.00..58.48 rows=3 width=50) (actual time=0.049..0.103
rows=3 loops=1)
-> Append (cost=0.00..58.48 rows=3 width=50) (actual time=0.041..0.074
rows=3 loops=1)
-> Seq Scan on sales (cost=0.00..2.79 rows=1 width=50) (actual
time=0.011..0.011 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date) AND (org = 7))
-> Seq Scan on sales_part3 sales (cost=0.00..27.85 rows=1
width=50) (actual time=0.007..0.007 rows=0 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date) AND (org = 7))
-> Seq Scan on sales_part4 sales (cost=0.00..27.85 rows=1
width=50) (actual time=0.007..0.020 rows=3 loops=1)
Filter: ((temps >= '2013-11-01'::date) AND (temps <=
'2014-10-01'::date) AND (org = 7))
Total runtime: 0.177 ms

En conclusion ....
Cela marche mais il est impératif d'éxaminer soigneusement la requete la
clause CHECK des tables.

je mesure la sensibilité :-(

Merci .

*Question subsidiaire* : il me semble avoir lu dans la documentation que
l'on ne devrait pas aller au delà de 100 partitions.

Est-ce encore d'actualité ?

​Merci ​

Pierre.

G+ <https://plus.google.com/u/0/107377830070954284209/about>

Le 5 octobre 2013 07:24, Pierre BOIZOT <pierre(dot)boizot(at)gmail(dot)com> a écrit :

> hello,
>
> oui oui le code ne provient pas des articles.
>
> c'est un extrait de code du cas qui m'occupe.
>
> Les clause de contrainte de la partition.
>
> Donc le partitionnement est fait sur un code et un interval de date.
>
> La table a 380 partition et en aura à terme 750 environs.
>
> Les requètes sont un peu lentes :-( + de 30 secondes.
>
> je recherche la cause ....
>
> la parametre contraint_exclusion est bien à on .
> malgré cela le plan cherche à parcourir toutes les partition de la table.
>
> d'ou ma question sur la relation entre les contraintes de la tables et
> les restrictions de la clause where.
>
> Y a t il une régle enoncée dans la documentation...
>
> s'il y a une différence entre contrainte et clause where cela
> revient il à intéroger la table sans les contraintes ?
>
> Je vais me faire un petit test pour explorer cela.
>
> ma question avait pour but de comprendre s'il y a des régles précises
> le point 5.9.4 et 5.9.6. de la documentation ne dit pas comment se
> comporte l'exclusion de contrainte dans le cas ou la clause where ne
> comporte pas toutes les colonnes déclarées dans la contrainte de la
> table.
>
> A+
> Pierre
>
>
>
>
>
> Pierre.
>
> G+
>
>
>
> Le 4 octobre 2013 23:39, Guillaume Lelarge <guillaume(at)lelarge(dot)info> a
> écrit :
> > On Fri, 2013-10-04 at 19:24 +0200, Pierre BOIZOT wrote:
> >> Effectivement google donne pas mal de resource sur le sujet.
> >>
> >> Deux on retenu mon attention.
> >>
> >>
> http://www.enterprisedb.com/resources-community/tutorials-quickstarts/all-platforms/how-partition-table-postgres-plus
> >>
> >>
> http://www.fuzzy.cz/en/articles/automatic-management-of-partitions-in-postgresql/
> >> 
> >>
> >>
> >> Je constate que les tables de partition ont des contraintes de ce style.
> >>
> >> CONSTRAINT analow_t20130924_pkey PRIMARY KEY (tor, trtime),
> >> CONSTRAINT analow_t20130924_check
> >> CHECK (lifetime::text = 'W'::text
> >> AND trtime >= to_date('20130924'::text, 'yyyymmdd'::text)
> >> AND trtime < to_date('20130925'::text, 'yyyymmdd'::text)
> >> )
> >>
> >> Mais que les requetes ne font références dans leur clause where.
> >> Qu'aux colonnes trtime et tor ...
> >>
> >> est-ce que les requetes doivent avoir les deux clauses lifetime
> intervalle
> >> de date ?
> >>
> >> est-ce une piste '
> >>
> >> Ce que je testerai ce week-end si c'est le cas.
> >>
> >
> > Je devrais peut-être allé me coucher. On est d'accord que le code des
> > contraintes ci-dessus ne fait pas partie des articles dont tu as donné
> > le lien ?
> >
> > Du coup, pourrais-tu donner un peu de contexte ?
> >
> >
> > --
> > Guillaume
> > http://blog.guillaume.lelarge.info
> > http://www.dalibo.com
> >
>

In response to

Responses

Browse pgsql-fr-generale by date

  From Date Subject
Next Message Pierre BOIZOT 2013-10-06 15:50:33 Re: psql : extension des commandes ...
Previous Message Guillaume Lelarge 2013-10-05 16:09:49 Re: psql : extension des commandes ...