Home Explore Blog CI



postgresql

18th chunk of `doc/src/sgml/perform.sgml`
449c3e1577dc2998e504e1855220df20bfcfce4056d579630000000100000fa4
 significant, especially on machines with slow
    <function>gettimeofday()</function> operating-system calls. You can use the
    <xref linkend="pgtesttiming"/> tool to measure the overhead of timing
    on your system.
   </para>

   <para>
    <command>EXPLAIN</command> results should not be extrapolated to situations
    much different from the one you are actually testing; for example,
    results on a toy-sized table cannot be assumed to apply to large tables.
    The planner's cost estimates are not linear and so it might choose
    a different plan for a larger or smaller table.  An extreme example
    is that on a table that only occupies one disk page, you'll nearly
    always get a sequential scan plan whether indexes are available or not.
    The planner realizes that it's going to take one disk page read to
    process the table in any case, so there's no value in expending additional
    page reads to look at an index.  (We saw this happening in the
    <literal>polygon_tbl</literal> example above.)
   </para>

   <para>
    There are cases in which the actual and estimated values won't match up
    well, but nothing is really wrong.  One such case occurs when
    plan node execution is stopped short by a <literal>LIMIT</literal> or similar
    effect.  For example, in the <literal>LIMIT</literal> query we used before,

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

                                                          QUERY PLAN
-------------------------------------------------------------------&zwsp;------------------------------------------------------------
 Limit  (cost=0.29..14.33 rows=2 width=244) (actual time=0.051..0.071 rows=2.00 loops=1)
   Buffers: shared hit=16
   -&gt;  Index Scan using tenk1_unique2 on tenk1  (cost=0.29..70.50 rows=10 width=244) (actual time=0.051..0.070 rows=2.00 loops=1)
         Index Cond: (unique2 &gt; 9000)
         Filter: (unique1 &lt; 100)
         Rows Removed by Filter: 287
         Index Searches: 1
         Buffers: shared hit=16
 Planning Time: 0.077 ms
 Execution Time: 0.086 ms
</screen>

    the estimated cost and row count for the Index Scan node are shown as
    though it were run to completion.  But in reality the Limit node stopped
    requesting rows after it got two, so the actual row count is only 2 and
    the run time is less than the cost estimate would suggest.  This is not
    an estimation error, only a discrepancy in the way the estimates and true
    values are displayed.
   </para>

   <para>
    Merge joins also have measurement artifacts that can confuse the unwary.
    A merge join will stop reading one input if it's exhausted the other input
    and the next key value in the one input is greater than the last key value
    of the other input; in such a case there can be no more matches and so no
    need to scan the rest of the first input.  This results in not reading all
    of one child, with results like those mentioned for <literal>LIMIT</literal>.
    Also, if the outer (first) child contains rows with duplicate key values,
    the inner (second) child is backed up and rescanned for the portion of its
    rows matching that key value.  <command>EXPLAIN ANALYZE</command> counts these
    repeated emissions of the same inner rows as if they were real additional
    rows.  When there are many outer duplicates, the reported actual row count
    for the inner child plan node can be significantly larger than the number
    of rows that are actually in the inner relation.
   </para>

   <para>
    BitmapAnd and BitmapOr nodes always report their actual row counts as zero,
    due to implementation limitations.
   </para>

   <para>
    Normally, <command>EXPLAIN</command> will display every plan node
    created by the planner.  However, there are cases where the executor
    can determine that certain nodes need not be executed because they
    cannot produce any rows, based on parameter values

Title: EXPLAIN ANALYZE Limitations and Special Cases
Summary
EXPLAIN ANALYZE results may not always accurately reflect the actual query performance due to various limitations and special cases, such as plan node execution being stopped short by LIMIT or similar effects, measurement artifacts in merge joins, and implementation limitations in BitmapAnd and BitmapOr nodes, which can lead to discrepancies between estimated and actual row counts and execution times.