values of the parameter.
</para>
<para>
A third possible use for partial indexes does not require the
index to be used in queries at all. The idea here is to create
a unique index over a subset of a table, as in <xref
linkend="indexes-partial-ex3"/>. This enforces uniqueness
among the rows that satisfy the index predicate, without constraining
those that do not.
</para>
<example id="indexes-partial-ex3">
<title>Setting up a Partial Unique Index</title>
<para>
Suppose that we have a table describing test outcomes. We wish
to ensure that there is only one <quote>successful</quote> entry for
a given subject and target combination, but there might be any number of
<quote>unsuccessful</quote> entries. Here is one way to do it:
<programlisting>
CREATE TABLE tests (
subject text,
target text,
success boolean,
...
);
CREATE UNIQUE INDEX tests_success_constraint ON tests (subject, target)
WHERE success;
</programlisting>
This is a particularly efficient approach when there are few
successful tests and many unsuccessful ones. It is also possible to
allow only one null in a column by creating a unique partial index
with an <literal>IS NULL</literal> restriction.
</para>
</example>
<para>
Finally, a partial index can also be used to override the system's
query plan choices. Also, data sets with peculiar
distributions might cause the system to use an index when it really
should not. In that case the index can be set up so that it is not
available for the offending query. Normally,
<productname>PostgreSQL</productname> makes reasonable choices about index
usage (e.g., it avoids them when retrieving common values, so the
earlier example really only saves index size, it is not required to
avoid index usage), and grossly incorrect plan choices are cause
for a bug report.
</para>
<para>
Keep in mind that setting up a partial index indicates that you
know at least as much as the query planner knows, in particular you
know when an index might be profitable. Forming this knowledge
requires experience and understanding of how indexes in
<productname>PostgreSQL</productname> work. In most cases, the
advantage of a partial index over a regular index will be minimal.
There are cases where they are quite counterproductive, as in <xref
linkend="indexes-partial-ex4"/>.
</para>
<example id="indexes-partial-ex4">
<title>Do Not Use Partial Indexes as a Substitute for Partitioning</title>
<para>
You might be tempted to create a large set of non-overlapping partial
indexes, for example
<programlisting>
CREATE INDEX mytable_cat_1 ON mytable (data) WHERE category = 1;
CREATE INDEX mytable_cat_2 ON mytable (data) WHERE category = 2;
CREATE INDEX mytable_cat_3 ON mytable (data) WHERE category = 3;
...
CREATE INDEX mytable_cat_<replaceable>N</replaceable> ON mytable (data) WHERE category = <replaceable>N</replaceable>;
</programlisting>
This is a bad idea! Almost certainly, you'll be better off with a
single non-partial index, declared like
<programlisting>
CREATE INDEX mytable_cat_data ON mytable (category, data);
</programlisting>
(Put the category column first, for the reasons described in
<xref linkend="indexes-multicolumn"/>.) While a search in this larger
index might have to descend through a couple more tree levels than a
search in a smaller index, that's almost certainly going to be cheaper
than the planner effort needed to select the appropriate one of the
partial indexes. The core of the problem is that the system does not
understand the relationship among the partial indexes, and will
laboriously test each one to see if it's applicable to the current
query.
</para>
<para>
If your table is large enough that a single index really is a bad idea,
you should look into using partitioning instead (see
<xref linkend="ddl-partitioning"/>).