Home Explore Blog CI



postgresql

9th chunk of `doc/src/sgml/indices.sgml`
a6fec3d9f0818d553cc659587da01e36023e41f2c6a159690000000100000fa8
 default, B-tree indexes store their entries in ascending order
   with nulls last (table TID is treated as a tiebreaker column among
   otherwise equal entries).  This means that a forward scan of an
   index on column <literal>x</literal> produces output satisfying <literal>ORDER BY x</literal>
   (or more verbosely, <literal>ORDER BY x ASC NULLS LAST</literal>).  The
   index can also be scanned backward, producing output satisfying
   <literal>ORDER BY x DESC</literal>
   (or more verbosely, <literal>ORDER BY x DESC NULLS FIRST</literal>, since
   <literal>NULLS FIRST</literal> is the default for <literal>ORDER BY DESC</literal>).
  </para>

  <para>
   You can adjust the ordering of a B-tree index by including the
   options <literal>ASC</literal>, <literal>DESC</literal>, <literal>NULLS FIRST</literal>,
   and/or <literal>NULLS LAST</literal> when creating the index; for example:
<programlisting>
CREATE INDEX test2_info_nulls_low ON test2 (info NULLS FIRST);
CREATE INDEX test3_desc_index ON test3 (id DESC NULLS LAST);
</programlisting>
   An index stored in ascending order with nulls first can satisfy
   either <literal>ORDER BY x ASC NULLS FIRST</literal> or
   <literal>ORDER BY x DESC NULLS LAST</literal> depending on which direction
   it is scanned in.
  </para>

  <para>
   You might wonder why bother providing all four options, when two
   options together with the possibility of backward scan would cover
   all the variants of <literal>ORDER BY</literal>.  In single-column indexes
   the options are indeed redundant, but in multicolumn indexes they can be
   useful.  Consider a two-column index on <literal>(x, y)</literal>: this can
   satisfy <literal>ORDER BY x, y</literal> if we scan forward, or
   <literal>ORDER BY x DESC, y DESC</literal> if we scan backward.
   But it might be that the application frequently needs to use
   <literal>ORDER BY x ASC, y DESC</literal>.  There is no way to get that
   ordering from a plain index, but it is possible if the index is defined
   as <literal>(x ASC, y DESC)</literal> or <literal>(x DESC, y ASC)</literal>.
  </para>

  <para>
   Obviously, indexes with non-default sort orderings are a fairly
   specialized feature, but sometimes they can produce tremendous
   speedups for certain queries.  Whether it's worth maintaining such an
   index depends on how often you use queries that require a special
   sort ordering.
  </para>
 </sect1>


 <sect1 id="indexes-bitmap-scans">
  <title>Combining Multiple Indexes</title>

  <indexterm zone="indexes-bitmap-scans">
   <primary>index</primary>
   <secondary>combining multiple indexes</secondary>
  </indexterm>

  <indexterm zone="indexes-bitmap-scans">
   <primary>bitmap scan</primary>
  </indexterm>

  <para>
   A single index scan can only use query clauses that use the index's
   columns with operators of its operator class and are joined with
   <literal>AND</literal>.  For example, given an index on <literal>(a, b)</literal>
   a query condition like <literal>WHERE a = 5 AND b = 6</literal> could
   use the index, but a query like <literal>WHERE a = 5 OR b = 6</literal> could not
   directly use the index.
  </para>

  <para>
   Fortunately,
   <productname>PostgreSQL</productname> has the ability to combine multiple indexes
   (including multiple uses of the same index) to handle cases that cannot
   be implemented by single index scans.  The system can form <literal>AND</literal>
   and <literal>OR</literal> conditions across several index scans.  For example,
   a query like <literal>WHERE x = 42 OR x = 47 OR x = 53 OR x = 99</literal>
   could be broken down into four separate scans of an index on <literal>x</literal>,
   each scan using one of the query clauses.  The results of these scans are
   then ORed together to produce the result.  Another example is that if we
   have separate indexes on <literal>x</literal> and <literal>y</literal>, one possible
   implementation of a query like <literal>WHERE x = 5 AND y = 6</literal>

Title: B-tree Index Ordering and Combining Multiple Indexes
Summary
This section discusses how to customize B-tree index ordering using `ASC`, `DESC`, `NULLS FIRST`, and `NULLS LAST`. While seemingly redundant for single-column indexes due to reverse scans, these options become useful in multicolumn indexes for specific ordering requirements like `ORDER BY x ASC, y DESC`. It highlights that while specialized, these indexes can greatly improve query speeds. The section then transitions to combining multiple indexes using bitmap scans to handle complex `AND` and `OR` conditions not possible with a single index scan.