mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-01-18 18:44:06 +08:00
doc: Reword old inheritance partitioning documentation
Prefer to use phrases like "child" instead of "partition" when describing the legacy inheritance-based partitioning. The word "partition" now has a fixed meaning for the built-in partitioning, so keeping it out of the documentation of the old method makes things clearer. Author: Justin Pryzby <pryzby@telsasoft.com>
This commit is contained in:
parent
17411e0ffa
commit
0c06534bd6
@ -3397,8 +3397,8 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
|
|||||||
Declarative partitioning only supports range, list and hash
|
Declarative partitioning only supports range, list and hash
|
||||||
partitioning, whereas table inheritance allows data to be divided in a
|
partitioning, whereas table inheritance allows data to be divided in a
|
||||||
manner of the user's choosing. (Note, however, that if constraint
|
manner of the user's choosing. (Note, however, that if constraint
|
||||||
exclusion is unable to prune partitions effectively, query performance
|
exclusion is unable to prune child tables effectively, query performance
|
||||||
will be very poor.)
|
might be poor.)
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
@ -3420,16 +3420,16 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
We use the same <structname>measurement</structname> table we used
|
We use the same <structname>measurement</structname> table we used
|
||||||
above. To implement it as a partitioned table using inheritance, use
|
above. To implement partitioning using inheritance, use
|
||||||
the following steps:
|
the following steps:
|
||||||
|
|
||||||
<orderedlist spacing="compact">
|
<orderedlist spacing="compact">
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Create the <quote>master</quote> table, from which all of the
|
Create the <quote>master</quote> table, from which all of the
|
||||||
partitions will inherit. This table will contain no data. Do not
|
<quote>child</quote> tables will inherit. This table will contain no data. Do not
|
||||||
define any check constraints on this table, unless you intend them
|
define any check constraints on this table, unless you intend them
|
||||||
to be applied equally to all partitions. There is no point in
|
to be applied equally to all child tables. There is no point in
|
||||||
defining any indexes or unique constraints on it, either. For our
|
defining any indexes or unique constraints on it, either. For our
|
||||||
example, the master table is the <structname>measurement</structname>
|
example, the master table is the <structname>measurement</structname>
|
||||||
table as originally defined.
|
table as originally defined.
|
||||||
@ -3441,7 +3441,7 @@ ALTER TABLE measurement ATTACH PARTITION measurement_y2008m02
|
|||||||
Create several <quote>child</quote> tables that each inherit from
|
Create several <quote>child</quote> tables that each inherit from
|
||||||
the master table. Normally, these tables will not add any columns
|
the master table. Normally, these tables will not add any columns
|
||||||
to the set inherited from the master. Just as with declarative
|
to the set inherited from the master. Just as with declarative
|
||||||
partitioning, these partitions are in every way normal
|
partitioning, these tables are in every way normal
|
||||||
<productname>PostgreSQL</productname> tables (or foreign tables).
|
<productname>PostgreSQL</productname> tables (or foreign tables).
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -3459,8 +3459,8 @@ CREATE TABLE measurement_y2008m01 () INHERITS (measurement);
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Add non-overlapping table constraints to the partition tables to
|
Add non-overlapping table constraints to the child tables to
|
||||||
define the allowed key values in each partition.
|
define the allowed key values in each.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -3471,18 +3471,18 @@ CHECK ( county IN ( 'Oxfordshire', 'Buckinghamshire', 'Warwickshire' ))
|
|||||||
CHECK ( outletID >= 100 AND outletID < 200 )
|
CHECK ( outletID >= 100 AND outletID < 200 )
|
||||||
</programlisting>
|
</programlisting>
|
||||||
Ensure that the constraints guarantee that there is no overlap
|
Ensure that the constraints guarantee that there is no overlap
|
||||||
between the key values permitted in different partitions. A common
|
between the key values permitted in different child tables. A common
|
||||||
mistake is to set up range constraints like:
|
mistake is to set up range constraints like:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CHECK ( outletID BETWEEN 100 AND 200 )
|
CHECK ( outletID BETWEEN 100 AND 200 )
|
||||||
CHECK ( outletID BETWEEN 200 AND 300 )
|
CHECK ( outletID BETWEEN 200 AND 300 )
|
||||||
</programlisting>
|
</programlisting>
|
||||||
This is wrong since it is not clear which partition the key value
|
This is wrong since it is not clear which child table the key
|
||||||
200 belongs in.
|
value 200 belongs in.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
It would be better to instead create partitions as follows:
|
It would be better to instead create child tables as follows:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE TABLE measurement_y2006m02 (
|
CREATE TABLE measurement_y2006m02 (
|
||||||
@ -3511,7 +3511,7 @@ CREATE TABLE measurement_y2008m01 (
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
For each partition, create an index on the key column(s),
|
For each child table, create an index on the key column(s),
|
||||||
as well as any other indexes you might want.
|
as well as any other indexes you might want.
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);
|
CREATE INDEX measurement_y2006m02_logdate ON measurement_y2006m02 (logdate);
|
||||||
@ -3527,9 +3527,9 @@ CREATE INDEX measurement_y2008m01_logdate ON measurement_y2008m01 (logdate);
|
|||||||
<para>
|
<para>
|
||||||
We want our application to be able to say <literal>INSERT INTO
|
We want our application to be able to say <literal>INSERT INTO
|
||||||
measurement ...</literal> and have the data be redirected into the
|
measurement ...</literal> and have the data be redirected into the
|
||||||
appropriate partition table. We can arrange that by attaching
|
appropriate child table. We can arrange that by attaching
|
||||||
a suitable trigger function to the master table.
|
a suitable trigger function to the master table.
|
||||||
If data will be added only to the latest partition, we can
|
If data will be added only to the latest child, we can
|
||||||
use a very simple trigger function:
|
use a very simple trigger function:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -3555,13 +3555,13 @@ CREATE TRIGGER insert_measurement_trigger
|
|||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
We must redefine the trigger function each month so that it always
|
We must redefine the trigger function each month so that it always
|
||||||
points to the current partition. The trigger definition does
|
points to the current child table. The trigger definition does
|
||||||
not need to be updated, however.
|
not need to be updated, however.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
We might want to insert data and have the server automatically
|
We might want to insert data and have the server automatically
|
||||||
locate the partition into which the row should be added. We
|
locate the child table into which the row should be added. We
|
||||||
could do this with a more complex trigger function, for example:
|
could do this with a more complex trigger function, for example:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -3589,7 +3589,7 @@ LANGUAGE plpgsql;
|
|||||||
|
|
||||||
The trigger definition is the same as before.
|
The trigger definition is the same as before.
|
||||||
Note that each <literal>IF</literal> test must exactly match the
|
Note that each <literal>IF</literal> test must exactly match the
|
||||||
<literal>CHECK</literal> constraint for its partition.
|
<literal>CHECK</literal> constraint for its child table.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -3600,8 +3600,8 @@ LANGUAGE plpgsql;
|
|||||||
|
|
||||||
<note>
|
<note>
|
||||||
<para>
|
<para>
|
||||||
In practice it might be best to check the newest partition first,
|
In practice, it might be best to check the newest child first,
|
||||||
if most inserts go into that partition. For simplicity we have
|
if most inserts go into that child. For simplicity, we have
|
||||||
shown the trigger's tests in the same order as in other parts
|
shown the trigger's tests in the same order as in other parts
|
||||||
of this example.
|
of this example.
|
||||||
</para>
|
</para>
|
||||||
@ -3609,7 +3609,7 @@ LANGUAGE plpgsql;
|
|||||||
|
|
||||||
<para>
|
<para>
|
||||||
A different approach to redirecting inserts into the appropriate
|
A different approach to redirecting inserts into the appropriate
|
||||||
partition table is to set up rules, instead of a trigger, on the
|
child table is to set up rules, instead of a trigger, on the
|
||||||
master table. For example:
|
master table. For example:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -3635,7 +3635,7 @@ DO INSTEAD
|
|||||||
<para>
|
<para>
|
||||||
Be aware that <command>COPY</command> ignores rules. If you want to
|
Be aware that <command>COPY</command> ignores rules. If you want to
|
||||||
use <command>COPY</command> to insert data, you'll need to copy into the
|
use <command>COPY</command> to insert data, you'll need to copy into the
|
||||||
correct partition table rather than into the master. <command>COPY</command>
|
correct child table rather than directly into the master. <command>COPY</command>
|
||||||
does fire triggers, so you can use it normally if you use the trigger
|
does fire triggers, so you can use it normally if you use the trigger
|
||||||
approach.
|
approach.
|
||||||
</para>
|
</para>
|
||||||
@ -3651,25 +3651,25 @@ DO INSTEAD
|
|||||||
<para>
|
<para>
|
||||||
Ensure that the <xref linkend="guc-constraint-exclusion"/>
|
Ensure that the <xref linkend="guc-constraint-exclusion"/>
|
||||||
configuration parameter is not disabled in
|
configuration parameter is not disabled in
|
||||||
<filename>postgresql.conf</filename>.
|
<filename>postgresql.conf</filename>; otherwise
|
||||||
If it is, queries will not be optimized as desired.
|
child tables may be accessed unnecessarily.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</orderedlist>
|
</orderedlist>
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
As we can see, a complex partitioning scheme could require a
|
As we can see, a complex table hierarchy could require a
|
||||||
substantial amount of DDL. In the above example we would be creating
|
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
|
a new child table each month, so it might be wise to write a script that
|
||||||
generates the required DDL automatically.
|
generates the required DDL automatically.
|
||||||
</para>
|
</para>
|
||||||
</sect3>
|
</sect3>
|
||||||
|
|
||||||
<sect3 id="ddl-partitioning-inheritance-maintenance">
|
<sect3 id="ddl-partitioning-inheritance-maintenance">
|
||||||
<title>Partition Maintenance</title>
|
<title>Maintenance for Inheritance Partitioning</title>
|
||||||
<para>
|
<para>
|
||||||
To remove old data quickly, simply drop the partition that is no longer
|
To remove old data quickly, simply drop the child table that is no longer
|
||||||
necessary:
|
necessary:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
DROP TABLE measurement_y2006m02;
|
DROP TABLE measurement_y2006m02;
|
||||||
@ -3677,7 +3677,7 @@ DROP TABLE measurement_y2006m02;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To remove the partition from the partitioned table but retain access to
|
To remove the child table from the inheritance hierarchy table but retain access to
|
||||||
it as a table in its own right:
|
it as a table in its own right:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
@ -3686,8 +3686,8 @@ ALTER TABLE measurement_y2006m02 NO INHERIT measurement;
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
To add a new partition to handle new data, create an empty partition
|
To add a new child table to handle new data, create an empty child table
|
||||||
just as the original partitions were created above:
|
just as the original children were created above:
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE TABLE measurement_y2008m02 (
|
CREATE TABLE measurement_y2008m02 (
|
||||||
@ -3695,9 +3695,10 @@ CREATE TABLE measurement_y2008m02 (
|
|||||||
) INHERITS (measurement);
|
) INHERITS (measurement);
|
||||||
</programlisting>
|
</programlisting>
|
||||||
|
|
||||||
Alternatively, one may want to create the new table outside the partition
|
Alternatively, one may want to create and populate the new child table
|
||||||
structure, and make it a partition after the data is loaded, checked,
|
before adding it to the table hierarchy. This could allow data to be
|
||||||
and transformed.
|
loaded, checked, and transformed before being made visible to queries on
|
||||||
|
the parent table.
|
||||||
|
|
||||||
<programlisting>
|
<programlisting>
|
||||||
CREATE TABLE measurement_y2008m02
|
CREATE TABLE measurement_y2008m02
|
||||||
@ -3715,7 +3716,7 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement;
|
|||||||
<title>Caveats</title>
|
<title>Caveats</title>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
The following caveats apply to partitioned tables implemented using
|
The following caveats apply to partitioning implemented using
|
||||||
inheritance:
|
inheritance:
|
||||||
<itemizedlist>
|
<itemizedlist>
|
||||||
<listitem>
|
<listitem>
|
||||||
@ -3723,19 +3724,19 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement;
|
|||||||
There is no automatic way to verify that all of the
|
There is no automatic way to verify that all of the
|
||||||
<literal>CHECK</literal> constraints are mutually
|
<literal>CHECK</literal> constraints are mutually
|
||||||
exclusive. It is safer to create code that generates
|
exclusive. It is safer to create code that generates
|
||||||
partitions and creates and/or modifies associated objects than
|
child tables and creates and/or modifies associated objects than
|
||||||
to write each by hand.
|
to write each by hand.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
The schemes shown here assume that the partition key column(s)
|
The schemes shown here assume that the values of a row's key column(s)
|
||||||
of a row never change, or at least do not change enough to require
|
never change, or at least do not change enough to require it to move to another partition.
|
||||||
it to move to another partition. An <command>UPDATE</command> that attempts
|
An <command>UPDATE</command> that attempts
|
||||||
to do that will fail because of the <literal>CHECK</literal> constraints.
|
to do that will fail because of the <literal>CHECK</literal> constraints.
|
||||||
If you need to handle such cases, you can put suitable update triggers
|
If you need to handle such cases, you can put suitable update triggers
|
||||||
on the partition tables, but it makes management of the structure
|
on the child tables, but it makes management of the structure
|
||||||
much more complicated.
|
much more complicated.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -3744,7 +3745,7 @@ ALTER TABLE measurement_y2008m02 INHERIT measurement;
|
|||||||
<para>
|
<para>
|
||||||
If you are using manual <command>VACUUM</command> or
|
If you are using manual <command>VACUUM</command> or
|
||||||
<command>ANALYZE</command> commands, don't forget that
|
<command>ANALYZE</command> commands, don't forget that
|
||||||
you need to run them on each partition individually. A command like:
|
you need to run them on each child table individually. A command like:
|
||||||
<programlisting>
|
<programlisting>
|
||||||
ANALYZE measurement;
|
ANALYZE measurement;
|
||||||
</programlisting>
|
</programlisting>
|
||||||
@ -3764,7 +3765,7 @@ ANALYZE measurement;
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Triggers or rules will be needed to route rows to the desired
|
Triggers or rules will be needed to route rows to the desired
|
||||||
partition, unless the application is explicitly aware of the
|
child table, unless the application is explicitly aware of the
|
||||||
partitioning scheme. Triggers may be complicated to write, and will
|
partitioning scheme. Triggers may be complicated to write, and will
|
||||||
be much slower than the tuple routing performed internally by
|
be much slower than the tuple routing performed internally by
|
||||||
declarative partitioning.
|
declarative partitioning.
|
||||||
@ -3935,7 +3936,7 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
|
|||||||
<para>
|
<para>
|
||||||
<firstterm>Constraint exclusion</firstterm> is a query optimization
|
<firstterm>Constraint exclusion</firstterm> is a query optimization
|
||||||
technique similar to partition pruning. While it is primarily used
|
technique similar to partition pruning. While it is primarily used
|
||||||
for partitioned tables using the legacy inheritance method, it can be
|
for partitioning implemented using the legacy inheritance method, it can be
|
||||||
used for other purposes, including with declarative partitioning.
|
used for other purposes, including with declarative partitioning.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
@ -3953,9 +3954,9 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
|
|||||||
The fact that constraint exclusion uses <literal>CHECK</literal>
|
The fact that constraint exclusion uses <literal>CHECK</literal>
|
||||||
constraints, which makes it slow compared to partition pruning, can
|
constraints, which makes it slow compared to partition pruning, can
|
||||||
sometimes be used as an advantage: because constraints can be defined
|
sometimes be used as an advantage: because constraints can be defined
|
||||||
even on declaratively-partitioned tables, in addition to the internal
|
even on declaratively-partitioned tables, in addition to their internal
|
||||||
partitioning constraints, and only constraint exclusion would be able
|
partition bounds, constraint exclusion may be able
|
||||||
to elide certain partitions from the query plan using those.
|
to elide additional partitions from the query plan.
|
||||||
</para>
|
</para>
|
||||||
|
|
||||||
<para>
|
<para>
|
||||||
@ -3986,7 +3987,7 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
|
|||||||
clause contains constants (or externally supplied parameters).
|
clause contains constants (or externally supplied parameters).
|
||||||
For example, a comparison against a non-immutable function such as
|
For example, a comparison against a non-immutable function such as
|
||||||
<function>CURRENT_TIMESTAMP</function> cannot be optimized, since the
|
<function>CURRENT_TIMESTAMP</function> cannot be optimized, since the
|
||||||
planner cannot know which partition the function's value might fall
|
planner cannot know which child table the function's value might fall
|
||||||
into at run time.
|
into at run time.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
@ -3994,7 +3995,7 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
|
|||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
Keep the partitioning constraints simple, else the planner may not be
|
Keep the partitioning constraints simple, else the planner may not be
|
||||||
able to prove that partitions don't need to be visited. Use simple
|
able to prove that child tables might not need to be visited. Use simple
|
||||||
equality conditions for list partitioning, or simple
|
equality conditions for list partitioning, or simple
|
||||||
range tests for range partitioning, as illustrated in the preceding
|
range tests for range partitioning, as illustrated in the preceding
|
||||||
examples. A good rule of thumb is that partitioning constraints should
|
examples. A good rule of thumb is that partitioning constraints should
|
||||||
@ -4006,11 +4007,11 @@ EXPLAIN SELECT count(*) FROM measurement WHERE logdate >= DATE '2008-01-01';
|
|||||||
|
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>
|
<para>
|
||||||
All constraints on all partitions of the master table are examined
|
All constraints on all children of the parent table are examined
|
||||||
during constraint exclusion, so large numbers of partitions are likely
|
during constraint exclusion, so large numbers of children are likely
|
||||||
to increase query planning time considerably. So the legacy
|
to increase query planning time considerably. So the legacy
|
||||||
inheritance based partitioning will work well with up to perhaps a
|
inheritance based partitioning will work well with up to perhaps a
|
||||||
hundred partitions; don't try to use many thousands of partitions.
|
hundred child tables; don't try to use many thousands of children.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user