Teach heapam code to know the difference between a real seqscan and the
authorTom Lane <tgl@sss.pgh.pa.us>
Sat, 9 Jun 2007 18:49:55 +0000 (18:49 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Sat, 9 Jun 2007 18:49:55 +0000 (18:49 +0000)
pseudo HeapScanDesc created for a bitmap heap scan.  This avoids some useless
overhead during a bitmap scan startup, in particular invoking the syncscan
code.  (We might someday want to do that, but right now it's merely useless
contention for shared memory, to say nothing of possibly pushing useful
entries out of syncscan's small LRU list.)  This also allows elimination of
ugly pgstat_discount_heap_scan() kluge.

src/backend/access/heap/heapam.c
src/backend/executor/nodeBitmapHeapscan.c
src/include/access/heapam.h
src/include/access/relscan.h
src/include/pgstat.h

index a0b561c209e046ce2ef00981ab9aa61520c4b88d..2c9dc9a949c14e0417587d0788eeff6e7ce36b04 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.235 2007/06/08 18:23:52 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/access/heap/heapam.c,v 1.236 2007/06/09 18:49:54 tgl Exp $
  *
  *
  * INTERFACE ROUTINES
 #include "utils/syscache.h"
 
 
+static HeapScanDesc heap_beginscan_internal(Relation relation,
+                                                                                       Snapshot snapshot,
+                                                                                       int nkeys, ScanKey key,
+                                                                                       bool is_bitmapscan);
 static XLogRecPtr log_heap_update(Relation reln, Buffer oldbuf,
                   ItemPointerData from, Buffer newbuf, HeapTuple newtup, bool move);
 
@@ -95,8 +99,9 @@ initscan(HeapScanDesc scan, ScanKey key)
         *
         * During a rescan, don't make a new strategy object if we don't have to.
         */
-       if (scan->rs_nblocks > NBuffers / 4 &&
-               !scan->rs_rd->rd_istemp)
+       if (!scan->rs_bitmapscan &&
+               !scan->rs_rd->rd_istemp &&
+               scan->rs_nblocks > NBuffers / 4)
        {
                if (scan->rs_strategy == NULL)
                        scan->rs_strategy = GetAccessStrategy(BAS_BULKREAD);
@@ -114,8 +119,6 @@ initscan(HeapScanDesc scan, ScanKey key)
                scan->rs_startblock = 0;
        }
 
-       /* rs_pageatatime was set when the snapshot was filled in */
-
        scan->rs_inited = false;
        scan->rs_ctup.t_data = NULL;
        ItemPointerSetInvalid(&scan->rs_ctup.t_self);
@@ -133,7 +136,12 @@ initscan(HeapScanDesc scan, ScanKey key)
        if (key != NULL)
                memcpy(scan->rs_key, key, scan->rs_nkeys * sizeof(ScanKeyData));
 
-       pgstat_count_heap_scan(scan->rs_rd);
+       /*
+        * Currently, we don't have a stats counter for bitmap heap scans
+        * (but the underlying bitmap index scans will be counted).
+        */
+       if (!scan->rs_bitmapscan)
+               pgstat_count_heap_scan(scan->rs_rd);
 }
 
 /*
@@ -1037,11 +1045,30 @@ heap_openrv(const RangeVar *relation, LOCKMODE lockmode)
 
 /* ----------------
  *             heap_beginscan  - begin relation scan
+ *
+ * heap_beginscan_bm is an alternate entry point for setting up a HeapScanDesc
+ * for a bitmap heap scan.  Although that scan technology is really quite
+ * unlike a standard seqscan, there is just enough commonality to make it
+ * worth using the same data structure.
  * ----------------
  */
 HeapScanDesc
 heap_beginscan(Relation relation, Snapshot snapshot,
                           int nkeys, ScanKey key)
+{
+       return heap_beginscan_internal(relation, snapshot, nkeys, key, false);
+}
+
+HeapScanDesc
+heap_beginscan_bm(Relation relation, Snapshot snapshot,
+                                 int nkeys, ScanKey key)
+{
+       return heap_beginscan_internal(relation, snapshot, nkeys, key, true);
+}
+
+static HeapScanDesc
+heap_beginscan_internal(Relation relation, Snapshot snapshot,
+                                               int nkeys, ScanKey key, bool is_bitmapscan)
 {
        HeapScanDesc scan;
 
@@ -1062,6 +1089,7 @@ heap_beginscan(Relation relation, Snapshot snapshot,
        scan->rs_rd = relation;
        scan->rs_snapshot = snapshot;
        scan->rs_nkeys = nkeys;
+       scan->rs_bitmapscan = is_bitmapscan;
        scan->rs_strategy = NULL;       /* set in initscan */
 
        /*
index 07729da2be68725e115bef6936e88cc0af79b452..c2ae755e014c7e04c62d21238b8a0e6946302043 100644 (file)
@@ -21,7 +21,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.17 2007/05/27 03:50:39 tgl Exp $
+ *       $PostgreSQL: pgsql/src/backend/executor/nodeBitmapHeapscan.c,v 1.18 2007/06/09 18:49:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -388,9 +388,6 @@ ExecBitmapHeapReScan(BitmapHeapScanState *node, ExprContext *exprCtxt)
        /* rescan to release any page pin */
        heap_rescan(node->ss.ss_currentScanDesc, NULL);
 
-       /* undo bogus "seq scan" count (see notes in ExecInitBitmapHeapScan) */
-       pgstat_discount_heap_scan(node->ss.ss_currentScanDesc->rs_rd);
-
        if (node->tbm)
                tbm_free(node->tbm);
        node->tbm = NULL;
@@ -522,20 +519,12 @@ ExecInitBitmapHeapScan(BitmapHeapScan *node, EState *estate, int eflags)
 
        /*
         * Even though we aren't going to do a conventional seqscan, it is useful
-        * to create a HeapScanDesc --- this checks the relation size and sets up
-        * statistical infrastructure for us.
-        */
-       scanstate->ss.ss_currentScanDesc = heap_beginscan(currentRelation,
-                                                                                                         estate->es_snapshot,
-                                                                                                         0,
-                                                                                                         NULL);
-
-       /*
-        * One problem is that heap_beginscan counts a "sequential scan" start,
-        * when we actually aren't doing any such thing.  Reverse out the added
-        * scan count.  (Eventually we may want to count bitmap scans separately.)
+        * to create a HeapScanDesc --- most of the fields in it are usable.
         */
-       pgstat_discount_heap_scan(scanstate->ss.ss_currentScanDesc->rs_rd);
+       scanstate->ss.ss_currentScanDesc = heap_beginscan_bm(currentRelation,
+                                                                                                                estate->es_snapshot,
+                                                                                                                0,
+                                                                                                                NULL);
 
        /*
         * get the scan type from the relation descriptor.
index 206159bdad7fd4a2eedd777f84afb5b21af4e045..cade6a26aa9dff38e0f1e8ec09183fbe085682d7 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.125 2007/06/08 18:23:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/heapam.h,v 1.126 2007/06/09 18:49:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -141,6 +141,8 @@ extern Relation heap_openrv(const RangeVar *relation, LOCKMODE lockmode);
 
 extern HeapScanDesc heap_beginscan(Relation relation, Snapshot snapshot,
                           int nkeys, ScanKey key);
+extern HeapScanDesc heap_beginscan_bm(Relation relation, Snapshot snapshot,
+                          int nkeys, ScanKey key);
 extern void heap_rescan(HeapScanDesc scan, ScanKey key);
 extern void heap_endscan(HeapScanDesc scan);
 extern HeapTuple heap_getnext(HeapScanDesc scan, ScanDirection direction);
index b45b2caabf19af25bb23b63b9a0e9b71a63cdbf3..15b9b8a337488bb56ba55a956c6576a926797398 100644 (file)
@@ -7,7 +7,7 @@
  * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.55 2007/06/08 18:23:53 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/access/relscan.h,v 1.56 2007/06/09 18:49:55 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -26,12 +26,13 @@ typedef struct HeapScanDescData
        Snapshot        rs_snapshot;    /* snapshot to see */
        int                     rs_nkeys;               /* number of scan keys */
        ScanKey         rs_key;                 /* array of scan key descriptors */
+       bool            rs_bitmapscan;  /* true if this is really a bitmap scan */
+       bool            rs_pageatatime; /* verify visibility page-at-a-time? */
 
        /* state set up at initscan time */
        BlockNumber rs_nblocks;         /* number of blocks to scan */
        BlockNumber     rs_startblock;  /* block # to start at */
        BufferAccessStrategy rs_strategy;       /* access strategy for reads */
-       bool            rs_pageatatime; /* verify visibility page-at-a-time? */
        bool            rs_syncscan;    /* report location to syncscan logic? */
 
        /* scan current state */
@@ -42,7 +43,7 @@ typedef struct HeapScanDescData
        /* NB: if rs_cbuf is not InvalidBuffer, we hold a pin on that buffer */
        ItemPointerData rs_mctid;       /* marked scan position, if any */
 
-       /* these fields only used in page-at-a-time mode */
+       /* these fields only used in page-at-a-time mode and for bitmap scans */
        int                     rs_cindex;              /* current tuple's index in vistuples */
        int                     rs_mindex;              /* marked tuple's saved index */
        int                     rs_ntuples;             /* number of visible tuples on page */
index ff050e6e451538656d531b2dddf7124e98ef2373..da910333531d5546c5a5a1e6cf533f242eba5122 100644 (file)
@@ -5,7 +5,7 @@
  *
  *     Copyright (c) 2001-2007, PostgreSQL Global Development Group
  *
- *     $PostgreSQL: pgsql/src/include/pgstat.h,v 1.61 2007/05/27 17:28:36 tgl Exp $
+ *     $PostgreSQL: pgsql/src/include/pgstat.h,v 1.62 2007/06/09 18:49:55 tgl Exp $
  * ----------
  */
 #ifndef PGSTAT_H
@@ -518,12 +518,6 @@ extern void pgstat_initstats(Relation rel);
                if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL)    \
                        (rel)->pgstat_info->t_counts.t_numscans++;                                      \
        } while (0)
-/* kluge for bitmap scans: */
-#define pgstat_discount_heap_scan(rel)                                                                 \
-       do {                                                                                                                            \
-               if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL)    \
-                       (rel)->pgstat_info->t_counts.t_numscans--;                                      \
-       } while (0)
 #define pgstat_count_heap_getnext(rel)                                                                 \
        do {                                                                                                                            \
                if (pgstat_collect_tuplelevel && (rel)->pgstat_info != NULL)    \