pg.ddx.io  pgsql-docs@postgresql.org mailing list archive  
help / color / mirror / Atom feed
From: David Fetter <david@fetter.org>
To: PostgreSQL Docs <pgsql-docs@postgresql.org>
Cc: PostgreSQL Patches <pgsql-patches@postgresql.org>
Subject: Re: Partition: use triggers instead of rules
Date: Wed, 28 Nov 2007 12:46:45 -0800
Message-ID: <20071128204644.GJ24146@fetter.org> (raw)
In-Reply-To: <20071128204120.GI24146@fetter.org>
References: <20071128202615.GG24146@fetter.org>
	<20071128123904.672beb8b@commandprompt.com>
	<20071128204120.GI24146@fetter.org>

On Wed, Nov 28, 2007 at 12:41:20PM -0800, David Fetter wrote:
> On Wed, Nov 28, 2007 at 12:39:04PM -0800, Joshua D. Drake wrote:
> > -----BEGIN PGP SIGNED MESSAGE-----
> > Hash: SHA1
> > 
> > On Wed, 28 Nov 2007 12:26:15 -0800
> > David Fetter <david@fetter.org> wrote:
> > 
> > > Folks,
> > > 
> > > Best practices for partitioning so far have shown that TRIGGERs are
> > > better than RULEs for most cases.  Please find attached a patch which
> > > reflects this.
> > > 
> > > Thanks to Robert Treat for help putting this together :)
> > > 
> > > Cheers,
> > > David.
> > 
> > +1
> > 
> > Joshua D. Drake
> 
> Per Robert, I've also dropped the UNION partitioning suggestion as
> it's pretty useless.

Oops.  Patch including *both* changes attached this time.

Cheers,
David.
-- 
David Fetter <david@fetter.org> http://fetter.org/
Phone: +1 415 235 3778  AIM: dfetter666  Yahoo!: dfetter
Skype: davidfetter      XMPP: david.fetter@gmail.com

Remember to vote!
Consider donating to Postgres: http://www.postgresql.org/about/donate

Attachments:

partition.diff (text/plain, 6.5K) download Index: doc/src/sgml/ddl.sgml =================================================================== RCS file: /projects/cvsroot/pgsql/doc/src/sgml/ddl.sgml,v retrieving revision 1.77 diff -c -r1.77 ddl.sgml *** doc/src/sgml/ddl.sgml 28 Nov 2007 15:42:31 -0000 1.77 --- doc/src/sgml/ddl.sgml 28 Nov 2007 20:44:57 -0000 *************** *** 2510,2564 **** <listitem> <para> If data will be added only to the latest partition, we can ! set up a very simple rule to insert data. We must ! redefine this each month so that it always points to the ! current partition: ! ! <programlisting> ! CREATE OR REPLACE RULE measurement_current_partition AS ! ON INSERT TO measurement ! DO INSTEAD ! INSERT INTO measurement_y2006m01 VALUES ( NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ); </programlisting> We might want to insert data and have the server automatically locate the partition into which the row should be added. We ! could do this with a more complex set of rules as shown below: <programlisting> ! CREATE RULE measurement_insert_y2004m02 AS ! ON INSERT TO measurement WHERE ! ( logdate &gt;= DATE '2004-02-01' AND logdate &lt; DATE '2004-03-01' ) ! DO INSTEAD ! INSERT INTO measurement_y2004m02 VALUES ( NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ); ! ... ! CREATE RULE measurement_insert_y2005m12 AS ! ON INSERT TO measurement WHERE ! ( logdate &gt;= DATE '2005-12-01' AND logdate &lt; DATE '2006-01-01' ) ! DO INSTEAD ! INSERT INTO measurement_y2005m12 VALUES ( NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ); ! CREATE RULE measurement_insert_y2006m01 AS ! ON INSERT TO measurement WHERE ! ( logdate &gt;= DATE '2006-01-01' AND logdate &lt; DATE '2006-02-01' ) ! DO INSTEAD ! INSERT INTO measurement_y2006m01 VALUES ( NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ); ! </programlisting> ! ! Note that the <literal>WHERE</literal> clause in each rule ! exactly matches the <literal>CHECK</literal> ! constraint for its partition. </para> </listitem> </orderedlist> --- 2510,2589 ---- <listitem> <para> If data will be added only to the latest partition, we can ! set up a very simple trigger function to insert data. We must ! redefine this each month so that it always points to the current ! partition: ! ! <programlisting> ! CREATE OR REPLACE FUNCTION measurement_current_partition() ! RETURNS TRIGGER ! LANGUAGE plpgsql ! AS $$ ! BEGIN ! INSERT INTO measurement_y2006m01 ! VALUES ( ! NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ! ); ! RETURN NEW; ! END; ! $$; ! </programlisting> ! ! The first time we create the table, we create a trigger which ! calls the above trigger function. When we replace the trigger ! function, we don't need to replace the trigger. ! ! <programlisting> ! CREATE TRIGGER insert_measurement_current_partition ! BEFORE INSERT ! ON measurement ! EXECUTE PROCEDURE measurement_current_partition(); </programlisting> We might want to insert data and have the server automatically locate the partition into which the row should be added. We ! could do this with a more complex trigger function as shown ! below: <programlisting> ! CREATE OR REPLACE FUNCTION measurement_insert() ! RETURNS TRIGGER ! LANGUAGE plpgsql ! AS $$ ! BEGIN ! IF ( logdate &gt;= DATE '2004-02-01' AND logdate &lt; DATE '2004-03-01' ) THEN ! ! INSERT INTO measurement_y2004m02 ! VALUES ( ! NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ! ); ! ELSIF ( logdate &gt;= DATE '2005-12-01' AND logdate &lt; DATE '2006-01-01' ) THEN ! ... ! ELSIF ( logdate &gt;= DATE '2008-01-01' AND logdate &lt; DATE '2006-02-01' ) THEN ! INSERT INTO measurement_y2008m01 ! VALUES ( ! NEW.city_id, ! NEW.logdate, ! NEW.peaktemp, ! NEW.unitsales ! ); ! ELSE ! RAISE EXCEPTION 'In, measurement_insert(), the date out of range. Fix the trigger function!'; ! END IF; ! RETURN NULL; ! END; ! $$; ! </programlisting> ! ! Note that the <literal>WHERE</literal> clause in each section ! of the trigger function exactly matches the ! <literal>CHECK</literal> constraint for its partition. </para> </listitem> </orderedlist> *************** *** 2568,2594 **** As we can see, a complex partitioning scheme could require a substantial amount of DDL. In the above example we would be creating a new partition each month, so it might be wise to write a ! script that generates the required DDL automatically. </para> - <para> - Partitioning can also be arranged using a <literal>UNION ALL</literal> - view: - - <programlisting> - CREATE VIEW measurement AS - SELECT * FROM measurement_y2004m02 - UNION ALL SELECT * FROM measurement_y2004m03 - ... - UNION ALL SELECT * FROM measurement_y2005m11 - UNION ALL SELECT * FROM measurement_y2005m12 - UNION ALL SELECT * FROM measurement_y2006m01; - </programlisting> - - However, the need to - recreate the view adds an extra step to adding and dropping - individual partitions of the data set. - </para> </sect2> <sect2 id="ddl-partitioning-managing-partitions"> --- 2593,2603 ---- As we can see, a complex partitioning scheme could require a substantial amount of DDL. In the above example we would be creating a new partition each month, so it might be wise to write a ! script that generates the required DDL automatically. You could ! also write a function to determine the partition dynamically ! before doing the INSERT. </para> </sect2> <sect2 id="ddl-partitioning-managing-partitions">

view thread (38+ messages)  latest in thread

Message-ID: <20071128204644.GJ24146@fetter.org>
Permalink:  ../20071128204644.GJ24146@fetter.org/
Also on:    postgresql.org/message-id/20071128204644.GJ24146@fetter.org

 ·  · 

reply

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Reply to all the recipients using the --to and --cc options:
  reply via email

  To: pgsql-docs@postgresql.org
  Cc: david@fetter.org, pgsql-patches@postgresql.org
  Subject: Re: Partition: use triggers instead of rules
  In-Reply-To: <20071128204644.GJ24146@fetter.org>

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

This inbox is served by DDX for PostgreSQL; see mirroring instructions
for how to clone and mirror all data and code used for this inbox