Home Explore Blog CI



postgresql

11th chunk of `doc/src/sgml/indices.sgml`
b045d48a6166a77a58c09c459aa6614e9008fc61cb999b490000000100000fa6
 queries involving only <literal>y</literal>.  Just
   how useful will depend on how effective the B-tree index skip scan
   optimization is; if <literal>x</literal> has no more than several hundred
   distinct values, skip scan will make searches for specific
   <literal>y</literal> values execute reasonably efficiently.  A combination
   of a multicolumn index on <literal>(x, y)</literal> and a separate index on
   <literal>y</literal> might also serve reasonably well.  For
   queries involving only <literal>x</literal>, the multicolumn index could be
   used, though it would be larger and hence slower than an index on
   <literal>x</literal> alone.  The last alternative is to create all three
   indexes, but this is probably only reasonable if the table is searched
   much more often than it is updated and all three types of query are
   common.  If one of the types of query is much less common than the
   others, you'd probably settle for creating just the two indexes that
   best match the common types.
  </para>

 </sect1>


 <sect1 id="indexes-unique">
  <title>Unique Indexes</title>

  <indexterm zone="indexes-unique">
   <primary>index</primary>
   <secondary>unique</secondary>
  </indexterm>

  <para>
   Indexes can also be used to enforce uniqueness of a column's value,
   or the uniqueness of the combined values of more than one column.
<synopsis>
CREATE UNIQUE INDEX <replaceable>name</replaceable> ON <replaceable>table</replaceable> (<replaceable>column</replaceable> <optional>, ...</optional>) <optional> NULLS <optional> NOT </optional> DISTINCT </optional>;
</synopsis>
   Currently, only B-tree indexes can be declared unique.
  </para>

  <para>
   When an index is declared unique, multiple table rows with equal
   indexed values are not allowed.  By default, null values in a unique column
   are not considered equal, allowing multiple nulls in the column.  The
   <literal>NULLS NOT DISTINCT</literal> option modifies this and causes the
   index to treat nulls as equal.  A multicolumn unique index will only reject
   cases where all indexed columns are equal in multiple rows.
  </para>

  <para>
   <productname>PostgreSQL</productname> automatically creates a unique
   index when a unique constraint or primary key is defined for a table.
   The index covers the columns that make up the primary key or unique
   constraint (a multicolumn index, if appropriate), and is the mechanism
   that enforces the constraint.
  </para>

  <note>
   <para>
    There's no need to manually
    create indexes on unique columns; doing so would just duplicate
    the automatically-created index.
   </para>
  </note>
 </sect1>


 <sect1 id="indexes-expressional">
  <title>Indexes on Expressions</title>

  <indexterm zone="indexes-expressional">
   <primary>index</primary>
   <secondary sortas="expressions">on expressions</secondary>
  </indexterm>

  <para>
   An index column need not be just a column of the underlying table,
   but can be a function or scalar expression computed from one or
   more columns of the table.  This feature is useful to obtain fast
   access to tables based on the results of computations.
  </para>

  <para>
   For example, a common way to do case-insensitive comparisons is to
   use the <function>lower</function> function:
<programlisting>
SELECT * FROM test1 WHERE lower(col1) = 'value';
</programlisting>
   This query can use an index if one has been
   defined on the result of the <literal>lower(col1)</literal>
   function:
<programlisting>
CREATE INDEX test1_lower_col1_idx ON test1 (lower(col1));
</programlisting>
  </para>

  <para>
   If we were to declare this index <literal>UNIQUE</literal>, it would prevent
   creation of rows whose <literal>col1</literal> values differ only in case,
   as well as rows whose <literal>col1</literal> values are actually identical.
   Thus, indexes on expressions can be used to enforce constraints that
   are not definable as simple unique constraints.
  </para>

  <para>

Title: Index Optimization Trade-offs, Unique Indexes, and Indexes on Expressions in PostgreSQL
Summary
The decision to use multicolumn indexes versus separate indexes requires balancing query needs. Multicolumn indexes can be more efficient for queries involving all columns, but less useful for those involving only some. B-tree index skip scan optimization can improve the performance of separate indexes. PostgreSQL automatically creates unique indexes for unique constraints or primary keys. Indexes on expressions can speed up queries based on computed values and can enforce constraints not definable as simple unique constraints.