usually a portion that is more useful for indexing than the
rest of the table. For example, if you have a table that contains both
billed and unbilled orders where the unbilled orders take up a small
fraction of the total table and yet that is an often used section, you
can improve performance by creating an index on just that portion.
Another possible application is to use <literal>WHERE</literal> with
<literal>UNIQUE</literal> to enforce uniqueness over a subset of a
table. See <xref linkend="indexes-partial"/> for more discussion.
</para>
<para>
The expression used in the <literal>WHERE</literal> clause can refer
only to columns of the underlying table, but it can use all columns,
not just the ones being indexed. Presently, subqueries and
aggregate expressions are also forbidden in <literal>WHERE</literal>.
The same restrictions apply to index fields that are expressions.
</para>
<para>
All functions and operators used in an index definition must be
<quote>immutable</quote>, that is, their results must depend only on
their arguments and never on any outside influence (such as
the contents of another table or the current time). This restriction
ensures that the behavior of the index is well-defined. To use a
user-defined function in an index expression or <literal>WHERE</literal>
clause, remember to mark the function immutable when you create it.
</para>
</refsect1>
<refsect1>
<title>Parameters</title>
<variablelist>
<varlistentry>
<term><literal>UNIQUE</literal></term>
<listitem>
<para>
Causes the system to check for
duplicate values in the table when the index is created (if data
already exist) and each time data is added. Attempts to
insert or update data which would result in duplicate entries
will generate an error.
</para>
<para>
Additional restrictions apply when unique indexes are applied to
partitioned tables; see <xref linkend="sql-createtable" />.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>CONCURRENTLY</literal></term>
<listitem>
<para>
When this option is used, <productname>PostgreSQL</productname> will build the
index without taking any locks that prevent concurrent inserts,
updates, or deletes on the table; whereas a standard index build
locks out writes (but not reads) on the table until it's done.
There are several caveats to be aware of when using this option
— see <xref linkend="sql-createindex-concurrently"/> below.
</para>
<para>
For temporary tables, <command>CREATE INDEX</command> is always
non-concurrent, as no other session can access them, and
non-concurrent index creation is cheaper.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>IF NOT EXISTS</literal></term>
<listitem>
<para>
Do not throw an error if a relation with the same name already exists.
A notice is issued in this case. Note that there is no guarantee that
the existing index is anything like the one that would have been created.
Index name is required when <literal>IF NOT EXISTS</literal> is specified.
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><literal>INCLUDE</literal></term>
<listitem>
<para>
The optional <literal>INCLUDE</literal> clause specifies a
list of columns which will be included in the index
as <firstterm>non-key</firstterm> columns. A non-key column cannot
be used in an index scan search qualification, and it is disregarded
for purposes of any uniqueness or exclusion constraint enforced by
the index. However, an index-only scan can return the contents of
non-key columns without having