Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 9d64632

Browse files
committed
Minor performance improvement: avoid unnecessary creation/unioning of
bitmaps for multiple indexscans. Instead just let each indexscan add TIDs directly into the BitmapOr node's result bitmap.
1 parent de4fbfa commit 9d64632

File tree

4 files changed

+65
-17
lines changed

4 files changed

+65
-17
lines changed

src/backend/executor/nodeBitmapAnd.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.1 2005/04/19 22:35:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.2 2005/04/20 15:48:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -46,6 +46,7 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate)
4646
PlanState **bitmapplanstates;
4747
int nplans;
4848
int i;
49+
ListCell *l;
4950
Plan *initNode;
5051

5152
CXT1_printf("ExecInitBitmapAnd: context is %d\n", CurrentMemoryContext);
@@ -78,10 +79,12 @@ ExecInitBitmapAnd(BitmapAnd *node, EState *estate)
7879
* call ExecInitNode on each of the plans to be executed and save the
7980
* results into the array "bitmapplanstates".
8081
*/
81-
for (i = 0; i < nplans; i++)
82+
i = 0;
83+
foreach(l, node->bitmapplans)
8284
{
83-
initNode = (Plan *) list_nth(node->bitmapplans, i);
85+
initNode = (Plan *) lfirst(l);
8486
bitmapplanstates[i] = ExecInitNode(initNode, estate);
87+
i++;
8588
}
8689

8790
return bitmapandstate;

src/backend/executor/nodeBitmapIndexscan.c

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.1 2005/04/19 22:35:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapIndexscan.c,v 1.2 2005/04/20 15:48:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -63,9 +63,21 @@ MultiExecBitmapIndexScan(BitmapIndexScanState *node)
6363
scandesc = node->biss_ScanDesc;
6464

6565
/*
66-
* Prepare result bitmap
66+
* Prepare the result bitmap. Normally we just create a new one to pass
67+
* back; however, our parent node is allowed to store a pre-made one
68+
* into node->biss_result, in which case we just OR our tuple IDs into
69+
* the existing bitmap. (This saves needing explicit UNION steps.)
6770
*/
68-
tbm = tbm_create(work_mem * 1024L);
71+
if (node->biss_result)
72+
{
73+
tbm = node->biss_result;
74+
node->biss_result = NULL; /* reset for next time */
75+
}
76+
else
77+
{
78+
/* XXX should we use less than work_mem for this? */
79+
tbm = tbm_create(work_mem * 1024L);
80+
}
6981

7082
/*
7183
* Get TIDs from index and insert into bitmap
@@ -271,6 +283,9 @@ ExecInitBitmapIndexScan(BitmapIndexScan *node, EState *estate)
271283
indexstate->ss.ps.plan = (Plan *) node;
272284
indexstate->ss.ps.state = estate;
273285

286+
/* normally we don't make the result bitmap till runtime */
287+
indexstate->biss_result = NULL;
288+
274289
/*
275290
* Miscellaneous initialization
276291
*

src/backend/executor/nodeBitmapOr.c

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapOr.c,v 1.1 2005/04/19 22:35:12 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapOr.c,v 1.2 2005/04/20 15:48:36 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -31,6 +31,7 @@
3131
#include "executor/execdebug.h"
3232
#include "executor/instrument.h"
3333
#include "executor/nodeBitmapOr.h"
34+
#include "miscadmin.h"
3435

3536

3637
/* ----------------------------------------------------------------
@@ -46,6 +47,7 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate)
4647
PlanState **bitmapplanstates;
4748
int nplans;
4849
int i;
50+
ListCell *l;
4951
Plan *initNode;
5052

5153
CXT1_printf("ExecInitBitmapOr: context is %d\n", CurrentMemoryContext);
@@ -78,10 +80,12 @@ ExecInitBitmapOr(BitmapOr *node, EState *estate)
7880
* call ExecInitNode on each of the plans to be executed and save the
7981
* results into the array "bitmapplanstates".
8082
*/
81-
for (i = 0; i < nplans; i++)
83+
i = 0;
84+
foreach(l, node->bitmapplans)
8285
{
83-
initNode = (Plan *) list_nth(node->bitmapplans, i);
86+
initNode = (Plan *) lfirst(l);
8487
bitmapplanstates[i] = ExecInitNode(initNode, estate);
88+
i++;
8589
}
8690

8791
return bitmaporstate;
@@ -128,17 +132,41 @@ MultiExecBitmapOr(BitmapOrState *node)
128132
PlanState *subnode = bitmapplans[i];
129133
TIDBitmap *subresult;
130134

131-
subresult = (TIDBitmap *) MultiExecProcNode(subnode);
135+
/*
136+
* We can special-case BitmapIndexScan children to avoid an
137+
* explicit tbm_union step for each child: just pass down the
138+
* current result bitmap and let the child OR directly into it.
139+
*/
140+
if (IsA(subnode, BitmapIndexScanState))
141+
{
142+
if (result == NULL) /* first subplan */
143+
{
144+
/* XXX should we use less than work_mem for this? */
145+
result = tbm_create(work_mem * 1024L);
146+
}
147+
148+
((BitmapIndexScanState *) subnode)->biss_result = result;
132149

133-
if (!subresult || !IsA(subresult, TIDBitmap))
134-
elog(ERROR, "unrecognized result from subplan");
150+
subresult = (TIDBitmap *) MultiExecProcNode(subnode);
135151

136-
if (result == NULL)
137-
result = subresult; /* first subplan */
152+
if (subresult != result)
153+
elog(ERROR, "unrecognized result from subplan");
154+
}
138155
else
139156
{
140-
tbm_union(result, subresult);
141-
tbm_free(subresult);
157+
/* standard implementation */
158+
subresult = (TIDBitmap *) MultiExecProcNode(subnode);
159+
160+
if (!subresult || !IsA(subresult, TIDBitmap))
161+
elog(ERROR, "unrecognized result from subplan");
162+
163+
if (result == NULL)
164+
result = subresult; /* first subplan */
165+
else
166+
{
167+
tbm_union(result, subresult);
168+
tbm_free(subresult);
169+
}
142170
}
143171
}
144172

src/include/nodes/execnodes.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.126 2005/04/19 22:35:17 tgl Exp $
10+
* $PostgreSQL: pgsql/src/include/nodes/execnodes.h,v 1.127 2005/04/20 15:48:36 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -901,6 +901,7 @@ typedef struct IndexScanState
901901
/* ----------------
902902
* BitmapIndexScanState information
903903
*
904+
* result bitmap to return output into, or NULL
904905
* ScanKeys Skey structures to scan index rel
905906
* NumScanKeys number of Skey structs
906907
* RuntimeKeyInfo array of exprstates for Skeys
@@ -914,6 +915,7 @@ typedef struct IndexScanState
914915
typedef struct BitmapIndexScanState
915916
{
916917
ScanState ss; /* its first field is NodeTag */
918+
TIDBitmap *biss_result;
917919
ScanKey biss_ScanKeys;
918920
int biss_NumScanKeys;
919921
ExprState **biss_RuntimeKeyInfo;

0 commit comments

Comments
 (0)