Tweak nodeBitmapAnd to stop evaluating sub-plan scans if it finds it's
got an empty bitmap after any step; the remaining subplans can no longer affect the result. Per a suggestion from Ilia Kantor.
This commit is contained in:
parent
75e90bbf69
commit
46a0eee300
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.2 2005/04/20 15:48:36 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/executor/nodeBitmapAnd.c,v 1.3 2005/08/28 22:47:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -143,6 +143,16 @@ MultiExecBitmapAnd(BitmapAndState *node)
|
||||||
tbm_intersect(result, subresult);
|
tbm_intersect(result, subresult);
|
||||||
tbm_free(subresult);
|
tbm_free(subresult);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If at any stage we have a completely empty bitmap, we can fall
|
||||||
|
* out without evaluating the remaining subplans, since ANDing them
|
||||||
|
* can no longer change the result. (Note: the fact that indxpath.c
|
||||||
|
* orders the subplans by selectivity should make this case more
|
||||||
|
* likely to occur.)
|
||||||
|
*/
|
||||||
|
if (tbm_is_empty(result))
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == NULL)
|
if (result == NULL)
|
||||||
|
|
|
@ -23,7 +23,7 @@
|
||||||
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/tidbitmap.c,v 1.5 2005/07/24 02:25:26 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/tidbitmap.c,v 1.6 2005/08/28 22:47:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -510,6 +510,15 @@ tbm_intersect_page(TIDBitmap *a, PagetableEntry *apage, const TIDBitmap *b)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* tbm_is_empty - is a TIDBitmap completely empty?
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
tbm_is_empty(const TIDBitmap *tbm)
|
||||||
|
{
|
||||||
|
return (tbm->nentries == 0);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* tbm_begin_iterate - prepare to iterate through a TIDBitmap
|
* tbm_begin_iterate - prepare to iterate through a TIDBitmap
|
||||||
*
|
*
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.187 2005/07/28 20:26:20 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/indxpath.c,v 1.188 2005/08/28 22:47:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -538,6 +538,11 @@ choose_bitmap_and(PlannerInfo *root, RelOptInfo *rel, List *paths)
|
||||||
* cases, the partial index will sort before competing non-partial
|
* cases, the partial index will sort before competing non-partial
|
||||||
* indexes and so it makes the right choice, but perhaps we need to
|
* indexes and so it makes the right choice, but perhaps we need to
|
||||||
* work harder.
|
* work harder.
|
||||||
|
*
|
||||||
|
* Note: outputting the selected sub-paths in selectivity order is a good
|
||||||
|
* thing even if we weren't using that as part of the selection method,
|
||||||
|
* because it makes the short-circuit case in MultiExecBitmapAnd() more
|
||||||
|
* likely to apply.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* Convert list to array so we can apply qsort */
|
/* Convert list to array so we can apply qsort */
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
*
|
*
|
||||||
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
* Copyright (c) 2003-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/tidbitmap.h,v 1.1 2005/04/17 22:24:02 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/tidbitmap.h,v 1.2 2005/08/28 22:47:20 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -49,6 +49,8 @@ extern void tbm_add_tuples(TIDBitmap *tbm, const ItemPointer tids, int ntids);
|
||||||
extern void tbm_union(TIDBitmap *a, const TIDBitmap *b);
|
extern void tbm_union(TIDBitmap *a, const TIDBitmap *b);
|
||||||
extern void tbm_intersect(TIDBitmap *a, const TIDBitmap *b);
|
extern void tbm_intersect(TIDBitmap *a, const TIDBitmap *b);
|
||||||
|
|
||||||
|
extern bool tbm_is_empty(const TIDBitmap *tbm);
|
||||||
|
|
||||||
extern void tbm_begin_iterate(TIDBitmap *tbm);
|
extern void tbm_begin_iterate(TIDBitmap *tbm);
|
||||||
extern TBMIterateResult *tbm_iterate(TIDBitmap *tbm);
|
extern TBMIterateResult *tbm_iterate(TIDBitmap *tbm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue