Home Explore Blog CI



postgresql

6th chunk of `doc/src/sgml/perform.sgml`
f1c9c123a7f106ceb05d5da7c404aad6962c65fd67e2081b0000000100000fa2
 (unique1 < 100)
         ->  Bitmap Index Scan on tenk1_unique2  (cost=0.00..19.78 rows=999 width=0)
               Index Cond: (unique2 > 9000)
</screen>

    But this requires visiting both indexes, so it's not necessarily a win
    compared to using just one index and treating the other condition as
    a filter.  If you vary the ranges involved you'll see the plan change
    accordingly.
   </para>

   <para>
    Here is an example showing the effects of <literal>LIMIT</literal>:

<screen>
EXPLAIN SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000 LIMIT 2;

                                     QUERY PLAN
-------------------------------------------------------------------&zwsp;------------------
 Limit  (cost=0.29..14.28 rows=2 width=244)
   -&gt;  Index Scan using tenk1_unique2 on tenk1  (cost=0.29..70.27 rows=10 width=244)
         Index Cond: (unique2 &gt; 9000)
         Filter: (unique1 &lt; 100)
</screen>
   </para>

   <para>
    This is the same query as above, but we added a <literal>LIMIT</literal> so that
    not all the rows need be retrieved, and the planner changed its mind about
    what to do.  Notice that the total cost and row count of the Index Scan
    node are shown as if it were run to completion.  However, the Limit node
    is expected to stop after retrieving only a fifth of those rows, so its
    total cost is only a fifth as much, and that's the actual estimated cost
    of the query.  This plan is preferred over adding a Limit node to the
    previous plan because the Limit could not avoid paying the startup cost
    of the bitmap scan, so the total cost would be something over 25 units
    with that approach.
   </para>

   <para>
    Let's try joining two tables, using the columns we have been discussing:

<screen>
EXPLAIN SELECT *
FROM tenk1 t1, tenk2 t2
WHERE t1.unique1 &lt; 10 AND t1.unique2 = t2.unique2;

                                      QUERY PLAN
-------------------------------------------------------------------&zwsp;-------------------
 Nested Loop  (cost=4.65..118.50 rows=10 width=488)
   -&gt;  Bitmap Heap Scan on tenk1 t1  (cost=4.36..39.38 rows=10 width=244)
         Recheck Cond: (unique1 &lt; 10)
         -&gt;  Bitmap Index Scan on tenk1_unique1  (cost=0.00..4.36 rows=10 width=0)
               Index Cond: (unique1 &lt; 10)
   -&gt;  Index Scan using tenk2_unique2 on tenk2 t2  (cost=0.29..7.90 rows=1 width=244)
         Index Cond: (unique2 = t1.unique2)
</screen>
   </para>

   <para>
    In this plan, we have a nested-loop join node with two table scans as
    inputs, or children.  The indentation of the node summary lines reflects
    the plan tree structure.  The join's first, or <quote>outer</quote>, child
    is a bitmap scan similar to those we saw before.  Its cost and row count
    are the same as we'd get from <literal>SELECT ... WHERE unique1 &lt; 10</literal>
    because we are
    applying the <literal>WHERE</literal> clause <literal>unique1 &lt; 10</literal>
    at that node.
    The <literal>t1.unique2 = t2.unique2</literal> clause is not relevant yet,
    so it doesn't affect the row count of the outer scan.  The nested-loop
    join node will run its second,
    or <quote>inner</quote> child once for each row obtained from the outer child.
    Column values from the current outer row can be plugged into the inner
    scan; here, the <literal>t1.unique2</literal> value from the outer row is available,
    so we get a plan and costs similar to what we saw above for a simple
    <literal>SELECT ... WHERE t2.unique2 = <replaceable>constant</replaceable></literal> case.
    (The estimated cost is actually a bit lower than what was seen above,
    as a result of caching that's expected to occur during the repeated
    index scans on <literal>t2</literal>.)  The
    costs of the loop node are then set on the basis of the cost of the outer
    scan, plus one repetition of the inner scan for each outer row (10 * 7.90,
    here), plus a little CPU

Title: Query Planning with Indexes, Joins, and Limits
Summary
This section explains how the planner optimizes queries with indexes, joins, and limits, including examples of nested-loop joins, bitmap index scans, and the effects of LIMIT on query planning, as well as how the planner estimates costs and row counts for different plan nodes, and how it uses caching to reduce costs in repeated index scans.