Home Explore Blog CI



postgresql

15th chunk of `doc/src/sgml/perform.sgml`
4bf75b8c48625b2afe2945012268f3e562cbf13c759514fd0000000100000fa2
    The planner thinks (quite correctly) that this sample table is too small
    to bother with an index scan, so we have a plain sequential scan in which
    all the rows got rejected by the filter condition.  But if we force an
    index scan to be used, we see:

<screen>
SET enable_seqscan TO off;

EXPLAIN ANALYZE SELECT * FROM polygon_tbl WHERE f1 @&gt; polygon '(0.5,2.0)';

                                                        QUERY PLAN
-------------------------------------------------------------------&zwsp;-------------------------------------------------------
 Index Scan using gpolygonind on polygon_tbl  (cost=0.13..8.15 rows=1 width=85) (actual time=0.074..0.074 rows=0.00 loops=1)
   Index Cond: (f1 @&gt; '((0.5,2))'::polygon)
   Rows Removed by Index Recheck: 1
   Index Searches: 1
   Buffers: shared hit=1
 Planning Time: 0.039 ms
 Execution Time: 0.098 ms
</screen>

    Here we can see that the index returned one candidate row, which was
    then rejected by a recheck of the index condition.  This happens because a
    GiST index is <quote>lossy</quote> for polygon containment tests: it actually
    returns the rows with polygons that overlap the target, and then we have
    to do the exact containment test on those rows.
   </para>

   <para>
    <command>EXPLAIN</command> has a <literal>BUFFERS</literal> option which
    provides additional detail about I/O operations performed during the
    planning and execution of the given query.  The buffer numbers displayed
    show the count of the non-distinct buffers hit, read, dirtied, and written
    for the given node and all of its child nodes.  The
    <literal>ANALYZE</literal> option implicitly enables the
    <literal>BUFFERS</literal> option.  If this
    is undesired, <literal>BUFFERS</literal> may be explicitly disabled:

<screen>
EXPLAIN (ANALYZE, BUFFERS OFF) SELECT * FROM tenk1 WHERE unique1 &lt; 100 AND unique2 &gt; 9000;

                                                           QUERY PLAN
-------------------------------------------------------------------&zwsp;--------------------------------------------------------------
 Bitmap Heap Scan on tenk1  (cost=25.07..60.11 rows=10 width=244) (actual time=0.105..0.114 rows=10.00 loops=1)
   Recheck Cond: ((unique1 &lt; 100) AND (unique2 &gt; 9000))
   Heap Blocks: exact=10
   -&gt;  BitmapAnd  (cost=25.07..25.07 rows=10 width=0) (actual time=0.100..0.101 rows=0.00 loops=1)
         -&gt;  Bitmap Index Scan on tenk1_unique1  (cost=0.00..5.04 rows=100 width=0) (actual time=0.027..0.027 rows=100.00 loops=1)
               Index Cond: (unique1 &lt; 100)
               Index Searches: 1
         -&gt;  Bitmap Index Scan on tenk1_unique2  (cost=0.00..19.78 rows=999 width=0) (actual time=0.070..0.070 rows=999.00 loops=1)
               Index Cond: (unique2 &gt; 9000)
               Index Searches: 1
 Planning Time: 0.162 ms
 Execution Time: 0.143 ms
</screen>
   </para>

   <para>
    Keep in mind that because <command>EXPLAIN ANALYZE</command> actually
    runs the query, any side-effects will happen as usual, even though
    whatever results the query might output are discarded in favor of
    printing the <command>EXPLAIN</command> data.  If you want to analyze a
    data-modifying query without changing your tables, you can
    roll the command back afterwards, for example:

<screen>
BEGIN;

EXPLAIN ANALYZE UPDATE tenk1 SET hundred = hundred + 1 WHERE unique1 &lt; 100;

                                                           QUERY PLAN
-------------------------------------------------------------------&zwsp;-------------------------------------------------------------
 Update on tenk1  (cost=5.06..225.23 rows=0 width=0) (actual time=1.634..1.635 rows=0.00 loops=1)
   -&gt;  Bitmap Heap Scan on tenk1  (cost=5.06..225.23 rows=100 width=10) (actual time=0.065..0.141 rows=100.00 loops=1)
         Recheck Cond: (unique1 &lt; 100)
         Heap Blocks: exact=90
         Buffers: shared hit=4 read=2
         -&gt;

Title: Using EXPLAIN and ANALYZE to Understand Query Performance
Summary
The EXPLAIN and ANALYZE commands provide detailed information about query plans, including index usage, buffer operations, and row removals, helping to optimize query performance, and can be used with options like BUFFERS to control the level of detail, while also considering the potential side effects of running data-modifying queries.