Home Explore Blog CI



postgresql

12th chunk of `doc/src/sgml/indices.sgml`
bd7578a6141df4f0a774e2c75ed6ceba1b031ba28c549c470000000100000fa4
 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>
   As another example, if one often does queries like:
<programlisting>
SELECT * FROM people WHERE (first_name || ' ' || last_name) = 'John Smith';
</programlisting>
   then it might be worth creating an index like this:
<programlisting>
CREATE INDEX people_names ON people ((first_name || ' ' || last_name));
</programlisting>
  </para>

  <para>
   The syntax of the <command>CREATE INDEX</command> command normally requires
   writing parentheses around index expressions, as shown in the second
   example.  The parentheses can be omitted when the expression is just
   a function call, as in the first example.
  </para>

  <para>
   Index expressions are relatively expensive to maintain, because the
   derived expression(s) must be computed for each row insertion
   and <link linkend="storage-hot">non-HOT update</link>. However, the index expressions are
   <emphasis>not</emphasis> recomputed during an indexed search, since they are
   already stored in the index.  In both examples above, the system
   sees the query as just <literal>WHERE indexedcolumn = 'constant'</literal>
   and so the speed of the search is equivalent to any other simple index
   query.  Thus, indexes on expressions are useful when retrieval speed
   is more important than insertion and update speed.
  </para>
 </sect1>


 <sect1 id="indexes-partial">
  <title>Partial Indexes</title>

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

  <para>
   A <firstterm>partial index</firstterm> is an index built over a
   subset of a table; the subset is defined by a conditional
   expression (called the <firstterm>predicate</firstterm> of the
   partial index).  The index contains entries only for those table
   rows that satisfy the predicate.  Partial indexes are a specialized
   feature, but there are several situations in which they are useful.
  </para>

  <para>
   One major reason for using a partial index is to avoid indexing common
   values.  Since a query searching for a common value (one that
   accounts for more than a few percent of all the table rows) will not
   use the index anyway, there is no point in keeping those rows in the
   index at all.  This reduces the size of the index, which will speed
   up those queries that do use the index.  It will also speed up many table
   update operations because the index does not need to be
   updated in all cases.  <xref linkend="indexes-partial-ex1"/> shows a
   possible application of this idea.
  </para>

  <example id="indexes-partial-ex1">
   <title>Setting up a Partial Index to Exclude Common Values</title>

   <para>
    Suppose you are storing web server access logs in a database.
    Most accesses originate from the IP address range of your organization but
    some are from elsewhere (say, employees on dial-up connections).
    If your searches by IP are primarily for outside accesses,
    you probably do not need to index the IP range that corresponds

Title: Examples and Considerations for Indexes on Expressions
Summary
Indexes can be created on expressions, such as functions applied to columns, to speed up queries based on computed values. An example is using an index on `lower(col1)` for case-insensitive searches. Declaring such an index as UNIQUE can enforce constraints that simple unique constraints cannot. The system sees the query as just WHERE indexedcolumn = 'constant' and so the speed of the search is equivalent to any other simple index query. However, maintaining these indexes involves computing the expression for each insertion/update, so they are most effective when retrieval speed outweighs insertion/update speed.