</sect1>
<sect1 id="ddl-partitioning">
<title>Table Partitioning</title>
<indexterm>
<primary>partitioning</primary>
</indexterm>
<indexterm>
<primary>table</primary>
<secondary>partitioning</secondary>
</indexterm>
<indexterm>
<primary>partitioned table</primary>
</indexterm>
<para>
<productname>PostgreSQL</productname> supports basic table
partitioning. This section describes why and how to implement
partitioning as part of your database design.
</para>
<sect2 id="ddl-partitioning-overview">
<title>Overview</title>
<para>
Partitioning refers to splitting what is logically one large table into
smaller physical pieces. Partitioning can provide several benefits:
<itemizedlist>
<listitem>
<para>
Query performance can be improved dramatically in certain situations,
particularly when most of the heavily accessed rows of the table are in a
single partition or a small number of partitions. Partitioning
effectively substitutes for the upper tree levels of indexes,
making it more likely that the heavily-used parts of the indexes
fit in memory.
</para>
</listitem>
<listitem>
<para>
When queries or updates access a large percentage of a single
partition, performance can be improved by using a
sequential scan of that partition instead of using an
index, which would require random-access reads scattered across the
whole table.
</para>
</listitem>
<listitem>
<para>
Bulk loads and deletes can be accomplished by adding or removing
partitions, if the usage pattern is accounted for in the
partitioning design. Dropping an individual partition
using <command>DROP TABLE</command>, or doing <command>ALTER TABLE
DETACH PARTITION</command>, is far faster than a bulk
operation. These commands also entirely avoid the
<command>VACUUM</command> overhead caused by a bulk <command>DELETE</command>.
</para>
</listitem>
<listitem>
<para>
Seldom-used data can be migrated to cheaper and slower storage media.
</para>
</listitem>
</itemizedlist>
These benefits will normally be worthwhile only when a table would
otherwise be very large. The exact point at which a table will
benefit from partitioning depends on the application, although a
rule of thumb is that the size of the table should exceed the physical
memory of the database server.
</para>
<para>
<productname>PostgreSQL</productname> offers built-in support for the
following forms of partitioning:
<variablelist>
<varlistentry id="ddl-partitioning-overview-range">
<term>Range Partitioning</term>
<listitem>
<para>
The table is partitioned into <quote>ranges</quote> defined
by a key column or set of columns, with no overlap between
the ranges of values assigned to different partitions. For
example, one might partition by date ranges, or by ranges of
identifiers for particular business objects.
Each range's bounds are understood as being inclusive at the
lower end and exclusive at the upper end. For example, if one
partition's range is from <literal>1</literal>
to <literal>10</literal>, and the next one's range is
from <literal>10</literal> to <literal>20</literal>, then
value <literal>10</literal> belongs to the second partition not
the first.
</para>
</listitem>
</varlistentry>
<varlistentry id="ddl-partitioning-overview-list">
<term>List Partitioning</term>
<listitem>
<para>
The table is partitioned by explicitly listing which key value(s)
appear in each partition.
</para>
</listitem>
</varlistentry>
<varlistentry