mirror of
https://github.com/postgres/postgres.git
synced 2025-06-16 06:01:02 +03:00
Rethink original decision to use AND/OR Expr nodes to represent bitmap
logic operations during planning. Seems cleaner to create two new Path node types, instead --- this avoids duplication of cost-estimation code. Also, create an enable_bitmapscan GUC parameter to control use of bitmap plans.
This commit is contained in:
@ -1,5 +1,5 @@
|
|||||||
<!--
|
<!--
|
||||||
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.313 2005/04/08 00:59:57 neilc Exp $
|
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.314 2005/04/21 19:18:12 tgl Exp $
|
||||||
-->
|
-->
|
||||||
|
|
||||||
<chapter Id="runtime">
|
<chapter Id="runtime">
|
||||||
@ -1768,6 +1768,22 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows
|
|||||||
</para>
|
</para>
|
||||||
|
|
||||||
<variablelist>
|
<variablelist>
|
||||||
|
<varlistentry id="guc-enable-bitmapscan" xreflabel="enable_bitmapscan">
|
||||||
|
<term><varname>enable_bitmapscan</varname> (<type>boolean</type>)</term>
|
||||||
|
<indexterm>
|
||||||
|
<primary>bitmap scan</primary>
|
||||||
|
</indexterm>
|
||||||
|
<indexterm>
|
||||||
|
<primary><varname>enable_bitmapscan</> configuration parameter</primary>
|
||||||
|
</indexterm>
|
||||||
|
<listitem>
|
||||||
|
<para>
|
||||||
|
Enables or disables the query planner's use of bitmap-scan plan
|
||||||
|
types. The default is on.
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry id="guc-enable-hashagg" xreflabel="enable_hashagg">
|
<varlistentry id="guc-enable-hashagg" xreflabel="enable_hashagg">
|
||||||
<term><varname>enable_hashagg</varname> (<type>boolean</type>)</term>
|
<term><varname>enable_hashagg</varname> (<type>boolean</type>)</term>
|
||||||
<indexterm>
|
<indexterm>
|
||||||
@ -4094,7 +4110,7 @@ plruby.bar = true # generates error, unknown class name
|
|||||||
|
|
||||||
<row>
|
<row>
|
||||||
<entry>
|
<entry>
|
||||||
<option>-fi</option>, <option>-fh</option>,
|
<option>-fb</option>, <option>-fh</option>, <option>-fi</option>,
|
||||||
<option>-fm</option>, <option>-fn</option>,
|
<option>-fm</option>, <option>-fn</option>,
|
||||||
<option>-fs</option>, <option>-ft</option><footnote
|
<option>-fs</option>, <option>-ft</option><footnote
|
||||||
id="fn.runtime-config-short">
|
id="fn.runtime-config-short">
|
||||||
@ -4111,8 +4127,9 @@ $ <userinput>postmaster -o '-S 1024 -s'</userinput>
|
|||||||
</footnote>
|
</footnote>
|
||||||
</entry>
|
</entry>
|
||||||
<entry>
|
<entry>
|
||||||
<literal>enable_indexscan = off</>,
|
<literal>enable_bitmapscan = off</>,
|
||||||
<literal>enable_hashjoin = off</>,
|
<literal>enable_hashjoin = off</>,
|
||||||
|
<literal>enable_indexscan = off</>,
|
||||||
<literal>enable_mergejoin = off</>,
|
<literal>enable_mergejoin = off</>,
|
||||||
<literal>enable_nestloop = off</>,
|
<literal>enable_nestloop = off</>,
|
||||||
<literal>enable_seqscan = off</>,
|
<literal>enable_seqscan = off</>,
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.248 2005/04/21 02:28:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.249 2005/04/21 19:18:12 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* Every node type that can appear in stored rules' parsetrees *must*
|
* Every node type that can appear in stored rules' parsetrees *must*
|
||||||
@ -1041,6 +1041,28 @@ _outBitmapHeapPath(StringInfo str, BitmapHeapPath *node)
|
|||||||
WRITE_FLOAT_FIELD(rows, "%.0f");
|
WRITE_FLOAT_FIELD(rows, "%.0f");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outBitmapAndPath(StringInfo str, BitmapAndPath *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("BITMAPANDPATH");
|
||||||
|
|
||||||
|
_outPathInfo(str, (Path *) node);
|
||||||
|
|
||||||
|
WRITE_NODE_FIELD(bitmapquals);
|
||||||
|
WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
_outBitmapOrPath(StringInfo str, BitmapOrPath *node)
|
||||||
|
{
|
||||||
|
WRITE_NODE_TYPE("BITMAPORPATH");
|
||||||
|
|
||||||
|
_outPathInfo(str, (Path *) node);
|
||||||
|
|
||||||
|
WRITE_NODE_FIELD(bitmapquals);
|
||||||
|
WRITE_FLOAT_FIELD(bitmapselectivity, "%.4f");
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
_outTidPath(StringInfo str, TidPath *node)
|
_outTidPath(StringInfo str, TidPath *node)
|
||||||
{
|
{
|
||||||
@ -1853,6 +1875,12 @@ _outNode(StringInfo str, void *obj)
|
|||||||
case T_BitmapHeapPath:
|
case T_BitmapHeapPath:
|
||||||
_outBitmapHeapPath(str, obj);
|
_outBitmapHeapPath(str, obj);
|
||||||
break;
|
break;
|
||||||
|
case T_BitmapAndPath:
|
||||||
|
_outBitmapAndPath(str, obj);
|
||||||
|
break;
|
||||||
|
case T_BitmapOrPath:
|
||||||
|
_outBitmapOrPath(str, obj);
|
||||||
|
break;
|
||||||
case T_TidPath:
|
case T_TidPath:
|
||||||
_outTidPath(str, obj);
|
_outTidPath(str, obj);
|
||||||
break;
|
break;
|
||||||
|
@ -255,6 +255,7 @@ RelOptInfo - a relation or joined relations
|
|||||||
Path - every way to generate a RelOptInfo(sequential,index,joins)
|
Path - every way to generate a RelOptInfo(sequential,index,joins)
|
||||||
SeqScan - a plain Path node with pathtype = T_SeqScan
|
SeqScan - a plain Path node with pathtype = T_SeqScan
|
||||||
IndexPath - index scans
|
IndexPath - index scans
|
||||||
|
BitmapHeapPath - top of a bitmapped index scan
|
||||||
TidPath - scan by CTID
|
TidPath - scan by CTID
|
||||||
AppendPath - append multiple subpaths together
|
AppendPath - append multiple subpaths together
|
||||||
ResultPath - a Result plan node (used for variable-free tlist or qual)
|
ResultPath - a Result plan node (used for variable-free tlist or qual)
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.126 2005/04/19 22:35:15 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.127 2005/04/21 19:18:12 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -901,6 +901,12 @@ print_path(Query *root, Path *path, int indent)
|
|||||||
case T_BitmapHeapPath:
|
case T_BitmapHeapPath:
|
||||||
ptype = "BitmapHeapScan";
|
ptype = "BitmapHeapScan";
|
||||||
break;
|
break;
|
||||||
|
case T_BitmapAndPath:
|
||||||
|
ptype = "BitmapAndPath";
|
||||||
|
break;
|
||||||
|
case T_BitmapOrPath:
|
||||||
|
ptype = "BitmapOrPath";
|
||||||
|
break;
|
||||||
case T_TidPath:
|
case T_TidPath:
|
||||||
ptype = "TidScan";
|
ptype = "TidScan";
|
||||||
break;
|
break;
|
||||||
|
@ -49,7 +49,7 @@
|
|||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.143 2005/04/21 02:28:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.144 2005/04/21 19:18:12 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -94,6 +94,7 @@ Cost disable_cost = 100000000.0;
|
|||||||
|
|
||||||
bool enable_seqscan = true;
|
bool enable_seqscan = true;
|
||||||
bool enable_indexscan = true;
|
bool enable_indexscan = true;
|
||||||
|
bool enable_bitmapscan = true;
|
||||||
bool enable_tidscan = true;
|
bool enable_tidscan = true;
|
||||||
bool enable_sort = true;
|
bool enable_sort = true;
|
||||||
bool enable_hashagg = true;
|
bool enable_hashagg = true;
|
||||||
@ -103,7 +104,7 @@ bool enable_hashjoin = true;
|
|||||||
|
|
||||||
|
|
||||||
static bool cost_qual_eval_walker(Node *node, QualCost *total);
|
static bool cost_qual_eval_walker(Node *node, QualCost *total);
|
||||||
static Selectivity cost_bitmap_qual(Node *bitmapqual, Cost *totalCost);
|
static void cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec);
|
||||||
static Selectivity approx_selectivity(Query *root, List *quals,
|
static Selectivity approx_selectivity(Query *root, List *quals,
|
||||||
JoinType jointype);
|
JoinType jointype);
|
||||||
static Selectivity join_in_selectivity(JoinPath *path, Query *root);
|
static Selectivity join_in_selectivity(JoinPath *path, Query *root);
|
||||||
@ -292,7 +293,7 @@ cost_index(IndexPath *path, Query *root,
|
|||||||
PointerGetDatum(&indexCorrelation));
|
PointerGetDatum(&indexCorrelation));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Save amcostestimate's results for possible use by cost_bitmap_scan.
|
* Save amcostestimate's results for possible use in bitmap scan planning.
|
||||||
* We don't bother to save indexStartupCost or indexCorrelation, because
|
* We don't bother to save indexStartupCost or indexCorrelation, because
|
||||||
* a bitmap scan doesn't care about either.
|
* a bitmap scan doesn't care about either.
|
||||||
*/
|
*/
|
||||||
@ -414,19 +415,19 @@ cost_index(IndexPath *path, Query *root,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cost_bitmap_scan
|
* cost_bitmap_heap_scan
|
||||||
* Determines and returns the cost of scanning a relation using a bitmap
|
* Determines and returns the cost of scanning a relation using a bitmap
|
||||||
* index-then-heap plan.
|
* index-then-heap plan.
|
||||||
*
|
*
|
||||||
* 'root' is the query root
|
* 'root' is the query root
|
||||||
* 'baserel' is the relation to be scanned
|
* 'baserel' is the relation to be scanned
|
||||||
* 'bitmapqual' is an AND/OR tree of IndexPaths for the component scans
|
* 'bitmapqual' is a tree of IndexPaths, BitmapAndPaths, and BitmapOrPaths
|
||||||
* 'is_injoin' is T if we are considering using the scan as the inside
|
* 'is_injoin' is T if we are considering using the scan as the inside
|
||||||
* of a nestloop join (hence, some of the quals are join clauses)
|
* of a nestloop join (hence, some of the quals are join clauses)
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
cost_bitmap_heap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
||||||
Node *bitmapqual, bool is_injoin)
|
Path *bitmapqual, bool is_injoin)
|
||||||
{
|
{
|
||||||
Cost startup_cost = 0;
|
Cost startup_cost = 0;
|
||||||
Cost run_cost = 0;
|
Cost run_cost = 0;
|
||||||
@ -443,15 +444,14 @@ cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
|||||||
Assert(baserel->relid > 0);
|
Assert(baserel->relid > 0);
|
||||||
Assert(baserel->rtekind == RTE_RELATION);
|
Assert(baserel->rtekind == RTE_RELATION);
|
||||||
|
|
||||||
if (!enable_indexscan) /* XXX use a separate enable flag? */
|
if (!enable_bitmapscan)
|
||||||
startup_cost += disable_cost;
|
startup_cost += disable_cost;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Estimate total cost of obtaining the bitmap, as well as its total
|
* Fetch total cost of obtaining the bitmap, as well as its total
|
||||||
* selectivity.
|
* selectivity.
|
||||||
*/
|
*/
|
||||||
indexTotalCost = 0;
|
cost_bitmap_tree_node(bitmapqual, &indexTotalCost, &indexSelectivity);
|
||||||
indexSelectivity = cost_bitmap_qual(bitmapqual, &indexTotalCost);
|
|
||||||
|
|
||||||
startup_cost += indexTotalCost;
|
startup_cost += indexTotalCost;
|
||||||
|
|
||||||
@ -497,22 +497,47 @@ cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* cost_bitmap_qual
|
* cost_bitmap_tree_node
|
||||||
* Recursively examine the AND/OR/IndexPath tree for a bitmap scan
|
* Extract cost and selectivity from a bitmap tree node (index/and/or)
|
||||||
*
|
|
||||||
* Total execution costs are added to *totalCost (so caller must be sure
|
|
||||||
* to initialize that to zero). Estimated total selectivity of the bitmap
|
|
||||||
* is returned as the function result.
|
|
||||||
*/
|
*/
|
||||||
static Selectivity
|
static void
|
||||||
cost_bitmap_qual(Node *bitmapqual, Cost *totalCost)
|
cost_bitmap_tree_node(Path *path, Cost *cost, Selectivity *selec)
|
||||||
{
|
{
|
||||||
Selectivity result;
|
if (IsA(path, IndexPath))
|
||||||
Selectivity subresult;
|
{
|
||||||
|
*cost = ((IndexPath *) path)->indextotalcost;
|
||||||
|
*selec = ((IndexPath *) path)->indexselectivity;
|
||||||
|
}
|
||||||
|
else if (IsA(path, BitmapAndPath))
|
||||||
|
{
|
||||||
|
*cost = path->total_cost;
|
||||||
|
*selec = ((BitmapAndPath *) path)->bitmapselectivity;
|
||||||
|
}
|
||||||
|
else if (IsA(path, BitmapOrPath))
|
||||||
|
{
|
||||||
|
*cost = path->total_cost;
|
||||||
|
*selec = ((BitmapOrPath *) path)->bitmapselectivity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
elog(ERROR, "unrecognized node type: %d", nodeTag(path));
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cost_bitmap_and_node
|
||||||
|
* Estimate the cost of a BitmapAnd node
|
||||||
|
*
|
||||||
|
* Note that this considers only the costs of index scanning and bitmap
|
||||||
|
* creation, not the eventual heap access. In that sense the object isn't
|
||||||
|
* truly a Path, but it has enough path-like properties (costs in particular)
|
||||||
|
* to warrant treating it as one.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cost_bitmap_and_node(BitmapAndPath *path, Query *root)
|
||||||
|
{
|
||||||
|
Cost totalCost;
|
||||||
|
Selectivity selec;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
if (and_clause(bitmapqual))
|
|
||||||
{
|
|
||||||
/*
|
/*
|
||||||
* We estimate AND selectivity on the assumption that the inputs
|
* We estimate AND selectivity on the assumption that the inputs
|
||||||
* are independent. This is probably often wrong, but we don't
|
* are independent. This is probably often wrong, but we don't
|
||||||
@ -521,20 +546,41 @@ cost_bitmap_qual(Node *bitmapqual, Cost *totalCost)
|
|||||||
* The runtime cost of the BitmapAnd itself is estimated at 100x
|
* The runtime cost of the BitmapAnd itself is estimated at 100x
|
||||||
* cpu_operator_cost for each tbm_intersect needed. Probably too
|
* cpu_operator_cost for each tbm_intersect needed. Probably too
|
||||||
* small, definitely too simplistic?
|
* small, definitely too simplistic?
|
||||||
*
|
|
||||||
* This must agree with make_bitmap_and in createplan.c.
|
|
||||||
*/
|
*/
|
||||||
result = 1.0;
|
totalCost = 0.0;
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
selec = 1.0;
|
||||||
|
foreach(l, path->bitmapquals)
|
||||||
{
|
{
|
||||||
subresult = cost_bitmap_qual((Node *) lfirst(l), totalCost);
|
Path *subpath = (Path *) lfirst(l);
|
||||||
result *= subresult;
|
Cost subCost;
|
||||||
if (l != list_head(((BoolExpr *) bitmapqual)->args))
|
Selectivity subselec;
|
||||||
*totalCost += 100.0 * cpu_operator_cost;
|
|
||||||
|
cost_bitmap_tree_node(subpath, &subCost, &subselec);
|
||||||
|
|
||||||
|
selec *= subselec;
|
||||||
|
|
||||||
|
totalCost += subCost;
|
||||||
|
if (l != list_head(path->bitmapquals))
|
||||||
|
totalCost += 100.0 * cpu_operator_cost;
|
||||||
}
|
}
|
||||||
}
|
path->bitmapselectivity = selec;
|
||||||
else if (or_clause(bitmapqual))
|
path->path.startup_cost = totalCost;
|
||||||
{
|
path->path.total_cost = totalCost;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* cost_bitmap_or_node
|
||||||
|
* Estimate the cost of a BitmapOr node
|
||||||
|
*
|
||||||
|
* See comments for cost_bitmap_and_node.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
cost_bitmap_or_node(BitmapOrPath *path, Query *root)
|
||||||
|
{
|
||||||
|
Cost totalCost;
|
||||||
|
Selectivity selec;
|
||||||
|
ListCell *l;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We estimate OR selectivity on the assumption that the inputs
|
* We estimate OR selectivity on the assumption that the inputs
|
||||||
* are non-overlapping, since that's often the case in "x IN (list)"
|
* are non-overlapping, since that's often the case in "x IN (list)"
|
||||||
@ -544,35 +590,27 @@ cost_bitmap_qual(Node *bitmapqual, Cost *totalCost)
|
|||||||
* cpu_operator_cost for each tbm_union needed. Probably too
|
* cpu_operator_cost for each tbm_union needed. Probably too
|
||||||
* small, definitely too simplistic? We are aware that the tbm_unions
|
* small, definitely too simplistic? We are aware that the tbm_unions
|
||||||
* are optimized out when the inputs are BitmapIndexScans.
|
* are optimized out when the inputs are BitmapIndexScans.
|
||||||
*
|
|
||||||
* This must agree with make_bitmap_or in createplan.c.
|
|
||||||
*/
|
*/
|
||||||
result = 0.0;
|
totalCost = 0.0;
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
selec = 0.0;
|
||||||
|
foreach(l, path->bitmapquals)
|
||||||
{
|
{
|
||||||
subresult = cost_bitmap_qual((Node *) lfirst(l), totalCost);
|
Path *subpath = (Path *) lfirst(l);
|
||||||
result += subresult;
|
Cost subCost;
|
||||||
if (l != list_head(((BoolExpr *) bitmapqual)->args) &&
|
Selectivity subselec;
|
||||||
!IsA((Node *) lfirst(l), IndexPath))
|
|
||||||
*totalCost += 100.0 * cpu_operator_cost;
|
|
||||||
}
|
|
||||||
result = Min(result, 1.0);
|
|
||||||
}
|
|
||||||
else if (IsA(bitmapqual, IndexPath))
|
|
||||||
{
|
|
||||||
IndexPath *ipath = (IndexPath *) bitmapqual;
|
|
||||||
|
|
||||||
/* this must agree with create_bitmap_subplan in createplan.c */
|
cost_bitmap_tree_node(subpath, &subCost, &subselec);
|
||||||
*totalCost += ipath->indextotalcost;
|
|
||||||
result = ipath->indexselectivity;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
elog(ERROR, "unrecognized node type: %d", nodeTag(bitmapqual));
|
|
||||||
result = 0.0; /* keep compiler quiet */
|
|
||||||
}
|
|
||||||
|
|
||||||
return result;
|
selec += subselec;
|
||||||
|
|
||||||
|
totalCost += subCost;
|
||||||
|
if (l != list_head(path->bitmapquals) &&
|
||||||
|
!IsA(subpath, IndexPath))
|
||||||
|
totalCost += 100.0 * cpu_operator_cost;
|
||||||
|
}
|
||||||
|
path->bitmapselectivity = Min(selec, 1.0);
|
||||||
|
path->path.startup_cost = totalCost;
|
||||||
|
path->path.total_cost = totalCost;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.181 2005/04/21 02:28:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/plan/createplan.c,v 1.182 2005/04/21 19:18:12 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -51,9 +51,9 @@ static IndexScan *create_indexscan_plan(Query *root, IndexPath *best_path,
|
|||||||
static BitmapHeapScan *create_bitmap_scan_plan(Query *root,
|
static BitmapHeapScan *create_bitmap_scan_plan(Query *root,
|
||||||
BitmapHeapPath *best_path,
|
BitmapHeapPath *best_path,
|
||||||
List *tlist, List *scan_clauses);
|
List *tlist, List *scan_clauses);
|
||||||
static Plan *create_bitmap_subplan(Query *root, Node *bitmapqual);
|
static Plan *create_bitmap_subplan(Query *root, Path *bitmapqual);
|
||||||
static List *create_bitmap_qual(Node *bitmapqual);
|
static List *create_bitmap_qual(Path *bitmapqual);
|
||||||
static List *create_bitmap_indxqual(Node *bitmapqual);
|
static List *create_bitmap_indxqual(Path *bitmapqual);
|
||||||
static TidScan *create_tidscan_plan(Query *root, TidPath *best_path,
|
static TidScan *create_tidscan_plan(Query *root, TidPath *best_path,
|
||||||
List *tlist, List *scan_clauses);
|
List *tlist, List *scan_clauses);
|
||||||
static SubqueryScan *create_subqueryscan_plan(Query *root, Path *best_path,
|
static SubqueryScan *create_subqueryscan_plan(Query *root, Path *best_path,
|
||||||
@ -928,37 +928,41 @@ create_bitmap_scan_plan(Query *root,
|
|||||||
* Given a bitmapqual tree, generate the Plan tree that implements it
|
* Given a bitmapqual tree, generate the Plan tree that implements it
|
||||||
*/
|
*/
|
||||||
static Plan *
|
static Plan *
|
||||||
create_bitmap_subplan(Query *root, Node *bitmapqual)
|
create_bitmap_subplan(Query *root, Path *bitmapqual)
|
||||||
{
|
{
|
||||||
Plan *plan;
|
Plan *plan;
|
||||||
Plan *subplan;
|
|
||||||
|
|
||||||
if (bitmapqual == NULL)
|
if (IsA(bitmapqual, BitmapAndPath))
|
||||||
return NULL; /* probably can't happen */
|
|
||||||
if (IsA(bitmapqual, List))
|
|
||||||
{
|
{
|
||||||
/* this case is to handle the List arguments of AND/OR */
|
BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
|
||||||
List *newlist = NIL;
|
List *newlist = NIL;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
foreach(l, (List *) bitmapqual)
|
foreach(l, apath->bitmapquals)
|
||||||
{
|
{
|
||||||
subplan = create_bitmap_subplan(root, lfirst(l));
|
Plan *subplan = create_bitmap_subplan(root, lfirst(l));
|
||||||
|
|
||||||
newlist = lappend(newlist, subplan);
|
newlist = lappend(newlist, subplan);
|
||||||
}
|
}
|
||||||
plan = (Plan *) newlist;
|
plan = (Plan *) make_bitmap_and(newlist);
|
||||||
|
copy_path_costsize(plan, bitmapqual);
|
||||||
|
plan->plan_width = 0; /* meaningless */
|
||||||
}
|
}
|
||||||
else if (and_clause(bitmapqual))
|
else if (IsA(bitmapqual, BitmapOrPath))
|
||||||
{
|
{
|
||||||
subplan = create_bitmap_subplan(root,
|
BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
|
||||||
(Node *) ((BoolExpr *) bitmapqual)->args);
|
List *newlist = NIL;
|
||||||
plan = (Plan *) make_bitmap_and((List *) subplan);
|
ListCell *l;
|
||||||
|
|
||||||
|
foreach(l, opath->bitmapquals)
|
||||||
|
{
|
||||||
|
Plan *subplan = create_bitmap_subplan(root, lfirst(l));
|
||||||
|
|
||||||
|
newlist = lappend(newlist, subplan);
|
||||||
}
|
}
|
||||||
else if (or_clause(bitmapqual))
|
plan = (Plan *) make_bitmap_or(newlist);
|
||||||
{
|
copy_path_costsize(plan, bitmapqual);
|
||||||
subplan = create_bitmap_subplan(root,
|
plan->plan_width = 0; /* meaningless */
|
||||||
(Node *) ((BoolExpr *) bitmapqual)->args);
|
|
||||||
plan = (Plan *) make_bitmap_or((List *) subplan);
|
|
||||||
}
|
}
|
||||||
else if (IsA(bitmapqual, IndexPath))
|
else if (IsA(bitmapqual, IndexPath))
|
||||||
{
|
{
|
||||||
@ -976,7 +980,6 @@ create_bitmap_subplan(Query *root, Node *bitmapqual)
|
|||||||
linitial(iscan->indxqualorig),
|
linitial(iscan->indxqualorig),
|
||||||
linitial(iscan->indxstrategy),
|
linitial(iscan->indxstrategy),
|
||||||
linitial(iscan->indxsubtype));
|
linitial(iscan->indxsubtype));
|
||||||
/* this must agree with cost_bitmap_qual in costsize.c */
|
|
||||||
bscan->scan.plan.startup_cost = 0.0;
|
bscan->scan.plan.startup_cost = 0.0;
|
||||||
bscan->scan.plan.total_cost = ipath->indextotalcost;
|
bscan->scan.plan.total_cost = ipath->indextotalcost;
|
||||||
bscan->scan.plan.plan_rows =
|
bscan->scan.plan.plan_rows =
|
||||||
@ -999,28 +1002,30 @@ create_bitmap_subplan(Query *root, Node *bitmapqual)
|
|||||||
* The result is expressed as an implicit-AND list.
|
* The result is expressed as an implicit-AND list.
|
||||||
*/
|
*/
|
||||||
static List *
|
static List *
|
||||||
create_bitmap_qual(Node *bitmapqual)
|
create_bitmap_qual(Path *bitmapqual)
|
||||||
{
|
{
|
||||||
List *result;
|
List *result;
|
||||||
List *sublist;
|
List *sublist;
|
||||||
|
|
||||||
if (and_clause(bitmapqual))
|
if (IsA(bitmapqual, BitmapAndPath))
|
||||||
{
|
{
|
||||||
|
BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
result = NIL;
|
result = NIL;
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
foreach(l, apath->bitmapquals)
|
||||||
{
|
{
|
||||||
sublist = create_bitmap_qual(lfirst(l));
|
sublist = create_bitmap_qual(lfirst(l));
|
||||||
result = list_concat(result, sublist);
|
result = list_concat(result, sublist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (or_clause(bitmapqual))
|
else if (IsA(bitmapqual, BitmapOrPath))
|
||||||
{
|
{
|
||||||
|
BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
|
||||||
List *newlist = NIL;
|
List *newlist = NIL;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
foreach(l, opath->bitmapquals)
|
||||||
{
|
{
|
||||||
sublist = create_bitmap_qual(lfirst(l));
|
sublist = create_bitmap_qual(lfirst(l));
|
||||||
if (sublist == NIL)
|
if (sublist == NIL)
|
||||||
@ -1056,26 +1061,29 @@ create_bitmap_qual(Node *bitmapqual)
|
|||||||
* to enforce, which may be weaker than the original qual expressions.
|
* to enforce, which may be weaker than the original qual expressions.
|
||||||
*/
|
*/
|
||||||
static List *
|
static List *
|
||||||
create_bitmap_indxqual(Node *bitmapqual)
|
create_bitmap_indxqual(Path *bitmapqual)
|
||||||
{
|
{
|
||||||
List *result;
|
List *result;
|
||||||
List *sublist;
|
List *sublist;
|
||||||
ListCell *l;
|
ListCell *l;
|
||||||
|
|
||||||
if (and_clause(bitmapqual))
|
if (IsA(bitmapqual, BitmapAndPath))
|
||||||
{
|
{
|
||||||
|
BitmapAndPath *apath = (BitmapAndPath *) bitmapqual;
|
||||||
|
|
||||||
result = NIL;
|
result = NIL;
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
foreach(l, apath->bitmapquals)
|
||||||
{
|
{
|
||||||
sublist = create_bitmap_indxqual(lfirst(l));
|
sublist = create_bitmap_indxqual(lfirst(l));
|
||||||
result = list_concat(result, sublist);
|
result = list_concat(result, sublist);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (or_clause(bitmapqual))
|
else if (IsA(bitmapqual, BitmapOrPath))
|
||||||
{
|
{
|
||||||
|
BitmapOrPath *opath = (BitmapOrPath *) bitmapqual;
|
||||||
List *newlist = NIL;
|
List *newlist = NIL;
|
||||||
|
|
||||||
foreach(l, ((BoolExpr *) bitmapqual)->args)
|
foreach(l, opath->bitmapquals)
|
||||||
{
|
{
|
||||||
sublist = create_bitmap_indxqual(lfirst(l));
|
sublist = create_bitmap_indxqual(lfirst(l));
|
||||||
if (sublist == NIL)
|
if (sublist == NIL)
|
||||||
@ -2067,34 +2075,8 @@ make_bitmap_and(List *bitmapplans)
|
|||||||
{
|
{
|
||||||
BitmapAnd *node = makeNode(BitmapAnd);
|
BitmapAnd *node = makeNode(BitmapAnd);
|
||||||
Plan *plan = &node->plan;
|
Plan *plan = &node->plan;
|
||||||
ListCell *subnode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute cost as sum of subplan costs, plus 100x cpu_operator_cost
|
|
||||||
* (a pretty arbitrary amount, agreed) for each tbm_intersect needed.
|
|
||||||
* This must agree with cost_bitmap_qual in costsize.c.
|
|
||||||
*/
|
|
||||||
plan->startup_cost = 0;
|
|
||||||
plan->total_cost = 0;
|
|
||||||
plan->plan_rows = 0;
|
|
||||||
plan->plan_width = 0; /* meaningless */
|
|
||||||
foreach(subnode, bitmapplans)
|
|
||||||
{
|
|
||||||
Plan *subplan = (Plan *) lfirst(subnode);
|
|
||||||
|
|
||||||
if (subnode == list_head(bitmapplans)) /* first node? */
|
|
||||||
{
|
|
||||||
plan->startup_cost = subplan->startup_cost;
|
|
||||||
plan->plan_rows = subplan->plan_rows;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
plan->total_cost += cpu_operator_cost * 100.0;
|
|
||||||
plan->plan_rows = Min(plan->plan_rows, subplan->plan_rows);
|
|
||||||
}
|
|
||||||
plan->total_cost += subplan->total_cost;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* cost should be inserted by caller */
|
||||||
plan->targetlist = NIL;
|
plan->targetlist = NIL;
|
||||||
plan->qual = NIL;
|
plan->qual = NIL;
|
||||||
plan->lefttree = NULL;
|
plan->lefttree = NULL;
|
||||||
@ -2109,32 +2091,8 @@ make_bitmap_or(List *bitmapplans)
|
|||||||
{
|
{
|
||||||
BitmapOr *node = makeNode(BitmapOr);
|
BitmapOr *node = makeNode(BitmapOr);
|
||||||
Plan *plan = &node->plan;
|
Plan *plan = &node->plan;
|
||||||
ListCell *subnode;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Compute cost as sum of subplan costs, plus 100x cpu_operator_cost
|
|
||||||
* (a pretty arbitrary amount, agreed) for each tbm_union needed.
|
|
||||||
* We assume that tbm_union can be optimized away for BitmapIndexScan
|
|
||||||
* subplans.
|
|
||||||
*
|
|
||||||
* This must agree with cost_bitmap_qual in costsize.c.
|
|
||||||
*/
|
|
||||||
plan->startup_cost = 0;
|
|
||||||
plan->total_cost = 0;
|
|
||||||
plan->plan_rows = 0;
|
|
||||||
plan->plan_width = 0; /* meaningless */
|
|
||||||
foreach(subnode, bitmapplans)
|
|
||||||
{
|
|
||||||
Plan *subplan = (Plan *) lfirst(subnode);
|
|
||||||
|
|
||||||
if (subnode == list_head(bitmapplans)) /* first node? */
|
|
||||||
plan->startup_cost = subplan->startup_cost;
|
|
||||||
else if (!IsA(subplan, BitmapIndexScan))
|
|
||||||
plan->total_cost += cpu_operator_cost * 100.0;
|
|
||||||
plan->total_cost += subplan->total_cost;
|
|
||||||
plan->plan_rows += subplan->plan_rows; /* ignore overlap */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
/* cost should be inserted by caller */
|
||||||
plan->targetlist = NIL;
|
plan->targetlist = NIL;
|
||||||
plan->qual = NIL;
|
plan->qual = NIL;
|
||||||
plan->lefttree = NULL;
|
plan->lefttree = NULL;
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.117 2005/04/21 02:28:01 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/util/pathnode.c,v 1.118 2005/04/21 19:18:12 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -475,12 +475,12 @@ create_index_path(Query *root,
|
|||||||
* create_bitmap_heap_path
|
* create_bitmap_heap_path
|
||||||
* Creates a path node for a bitmap scan.
|
* Creates a path node for a bitmap scan.
|
||||||
*
|
*
|
||||||
* 'bitmapqual' is an AND/OR tree of IndexPath nodes.
|
* 'bitmapqual' is a tree of IndexPath, BitmapAndPath, and BitmapOrPath nodes.
|
||||||
*/
|
*/
|
||||||
BitmapHeapPath *
|
BitmapHeapPath *
|
||||||
create_bitmap_heap_path(Query *root,
|
create_bitmap_heap_path(Query *root,
|
||||||
RelOptInfo *rel,
|
RelOptInfo *rel,
|
||||||
Node *bitmapqual)
|
Path *bitmapqual)
|
||||||
{
|
{
|
||||||
BitmapHeapPath *pathnode = makeNode(BitmapHeapPath);
|
BitmapHeapPath *pathnode = makeNode(BitmapHeapPath);
|
||||||
|
|
||||||
@ -499,7 +499,53 @@ create_bitmap_heap_path(Query *root,
|
|||||||
*/
|
*/
|
||||||
pathnode->rows = rel->rows;
|
pathnode->rows = rel->rows;
|
||||||
|
|
||||||
cost_bitmap_scan(&pathnode->path, root, rel, bitmapqual, false);
|
cost_bitmap_heap_scan(&pathnode->path, root, rel, bitmapqual, false);
|
||||||
|
|
||||||
|
return pathnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create_bitmap_and_path
|
||||||
|
* Creates a path node representing a BitmapAnd.
|
||||||
|
*/
|
||||||
|
BitmapAndPath *
|
||||||
|
create_bitmap_and_path(Query *root,
|
||||||
|
RelOptInfo *rel,
|
||||||
|
List *bitmapquals)
|
||||||
|
{
|
||||||
|
BitmapAndPath *pathnode = makeNode(BitmapAndPath);
|
||||||
|
|
||||||
|
pathnode->path.pathtype = T_BitmapAnd;
|
||||||
|
pathnode->path.parent = rel;
|
||||||
|
pathnode->path.pathkeys = NIL; /* always unordered */
|
||||||
|
|
||||||
|
pathnode->bitmapquals = bitmapquals;
|
||||||
|
|
||||||
|
/* this sets bitmapselectivity as well as the regular cost fields: */
|
||||||
|
cost_bitmap_and_node(pathnode, root);
|
||||||
|
|
||||||
|
return pathnode;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* create_bitmap_or_path
|
||||||
|
* Creates a path node representing a BitmapOr.
|
||||||
|
*/
|
||||||
|
BitmapOrPath *
|
||||||
|
create_bitmap_or_path(Query *root,
|
||||||
|
RelOptInfo *rel,
|
||||||
|
List *bitmapquals)
|
||||||
|
{
|
||||||
|
BitmapOrPath *pathnode = makeNode(BitmapOrPath);
|
||||||
|
|
||||||
|
pathnode->path.pathtype = T_BitmapOr;
|
||||||
|
pathnode->path.parent = rel;
|
||||||
|
pathnode->path.pathkeys = NIL; /* always unordered */
|
||||||
|
|
||||||
|
pathnode->bitmapquals = bitmapquals;
|
||||||
|
|
||||||
|
/* this sets bitmapselectivity as well as the regular cost fields: */
|
||||||
|
cost_bitmap_or_node(pathnode, root);
|
||||||
|
|
||||||
return pathnode;
|
return pathnode;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@
|
|||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.442 2005/02/22 04:37:17 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/tcop/postgres.c,v 1.443 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
* NOTES
|
* NOTES
|
||||||
* this is the "main" module of the postgres backend and
|
* this is the "main" module of the postgres backend and
|
||||||
@ -2371,6 +2371,9 @@ PostgresMain(int argc, char *argv[], const char *username)
|
|||||||
case 'i': /* indexscan */
|
case 'i': /* indexscan */
|
||||||
tmp = "enable_indexscan";
|
tmp = "enable_indexscan";
|
||||||
break;
|
break;
|
||||||
|
case 'b': /* bitmapscan */
|
||||||
|
tmp = "enable_bitmapscan";
|
||||||
|
break;
|
||||||
case 't': /* tidscan */
|
case 't': /* tidscan */
|
||||||
tmp = "enable_tidscan";
|
tmp = "enable_tidscan";
|
||||||
break;
|
break;
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
* Written by Peter Eisentraut <peter_e@gmx.net>.
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.259 2005/04/13 18:54:56 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/utils/misc/guc.c,v 1.260 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*--------------------------------------------------------------------
|
*--------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -369,6 +369,14 @@ static struct config_bool ConfigureNamesBool[] =
|
|||||||
&enable_indexscan,
|
&enable_indexscan,
|
||||||
true, NULL, NULL
|
true, NULL, NULL
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
{"enable_bitmapscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
||||||
|
gettext_noop("Enables the planner's use of bitmap-scan plans."),
|
||||||
|
NULL
|
||||||
|
},
|
||||||
|
&enable_bitmapscan,
|
||||||
|
true, NULL, NULL
|
||||||
|
},
|
||||||
{
|
{
|
||||||
{"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
{"enable_tidscan", PGC_USERSET, QUERY_TUNING_METHOD,
|
||||||
gettext_noop("Enables the planner's use of TID scan plans."),
|
gettext_noop("Enables the planner's use of TID scan plans."),
|
||||||
|
@ -137,6 +137,7 @@
|
|||||||
|
|
||||||
# - Planner Method Configuration -
|
# - Planner Method Configuration -
|
||||||
|
|
||||||
|
#enable_bitmapscan = true
|
||||||
#enable_hashagg = true
|
#enable_hashagg = true
|
||||||
#enable_hashjoin = true
|
#enable_hashjoin = true
|
||||||
#enable_indexscan = true
|
#enable_indexscan = true
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
|
* Copyright (c) 2000-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.124 2005/04/07 01:51:39 neilc Exp $
|
* $PostgreSQL: pgsql/src/bin/psql/tab-complete.c,v 1.125 2005/04/21 19:18:13 tgl Exp $
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*----------------------------------------------------------------------
|
/*----------------------------------------------------------------------
|
||||||
@ -533,6 +533,7 @@ psql_completion(char *text, int start, int end)
|
|||||||
"default_with_oids",
|
"default_with_oids",
|
||||||
"dynamic_library_path",
|
"dynamic_library_path",
|
||||||
"effective_cache_size",
|
"effective_cache_size",
|
||||||
|
"enable_bitmapscan",
|
||||||
"enable_hashagg",
|
"enable_hashagg",
|
||||||
"enable_hashjoin",
|
"enable_hashjoin",
|
||||||
"enable_indexscan",
|
"enable_indexscan",
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.167 2005/04/19 22:35:17 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/nodes.h,v 1.168 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -170,6 +170,8 @@ typedef enum NodeTag
|
|||||||
T_Path,
|
T_Path,
|
||||||
T_IndexPath,
|
T_IndexPath,
|
||||||
T_BitmapHeapPath,
|
T_BitmapHeapPath,
|
||||||
|
T_BitmapAndPath,
|
||||||
|
T_BitmapOrPath,
|
||||||
T_NestPath,
|
T_NestPath,
|
||||||
T_MergePath,
|
T_MergePath,
|
||||||
T_HashPath,
|
T_HashPath,
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.106 2005/04/21 02:28:02 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/nodes/relation.h,v 1.107 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -406,7 +406,7 @@ typedef struct IndexPath
|
|||||||
* out in physical heap order no matter what the underlying indexes did.
|
* out in physical heap order no matter what the underlying indexes did.
|
||||||
*
|
*
|
||||||
* The individual indexscans are represented by IndexPath nodes, and any
|
* The individual indexscans are represented by IndexPath nodes, and any
|
||||||
* logic on top of them is represented by regular AND and OR expressions.
|
* logic on top of them is represented by BitmapAndPath and BitmapOrPath.
|
||||||
* Notice that we can use the same IndexPath node both to represent a regular
|
* Notice that we can use the same IndexPath node both to represent a regular
|
||||||
* IndexScan plan, and as the child of a BitmapHeapPath that represents
|
* IndexScan plan, and as the child of a BitmapHeapPath that represents
|
||||||
* scanning the same index using a BitmapIndexScan. The startup_cost and
|
* scanning the same index using a BitmapIndexScan. The startup_cost and
|
||||||
@ -420,11 +420,37 @@ typedef struct IndexPath
|
|||||||
typedef struct BitmapHeapPath
|
typedef struct BitmapHeapPath
|
||||||
{
|
{
|
||||||
Path path;
|
Path path;
|
||||||
Node *bitmapqual; /* the IndexPath/AND/OR tree */
|
Path *bitmapqual; /* IndexPath, BitmapAndPath, BitmapOrPath */
|
||||||
bool isjoininner; /* T if it's a nestloop inner scan */
|
bool isjoininner; /* T if it's a nestloop inner scan */
|
||||||
double rows; /* estimated number of result tuples */
|
double rows; /* estimated number of result tuples */
|
||||||
} BitmapHeapPath;
|
} BitmapHeapPath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BitmapAndPath represents a BitmapAnd plan node; it can only appear as
|
||||||
|
* part of the substructure of a BitmapHeapPath. The Path structure is
|
||||||
|
* a bit more heavyweight than we really need for this, but for simplicity
|
||||||
|
* we make it a derivative of Path anyway.
|
||||||
|
*/
|
||||||
|
typedef struct BitmapAndPath
|
||||||
|
{
|
||||||
|
Path path;
|
||||||
|
List *bitmapquals; /* IndexPaths and BitmapOrPaths */
|
||||||
|
Selectivity bitmapselectivity;
|
||||||
|
} BitmapAndPath;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* BitmapOrPath represents a BitmapOr plan node; it can only appear as
|
||||||
|
* part of the substructure of a BitmapHeapPath. The Path structure is
|
||||||
|
* a bit more heavyweight than we really need for this, but for simplicity
|
||||||
|
* we make it a derivative of Path anyway.
|
||||||
|
*/
|
||||||
|
typedef struct BitmapOrPath
|
||||||
|
{
|
||||||
|
Path path;
|
||||||
|
List *bitmapquals; /* IndexPaths and BitmapAndPaths */
|
||||||
|
Selectivity bitmapselectivity;
|
||||||
|
} BitmapOrPath;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TidPath represents a scan by TID
|
* TidPath represents a scan by TID
|
||||||
*
|
*
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.65 2005/04/21 02:28:02 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/optimizer/cost.h,v 1.66 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -42,6 +42,7 @@ extern double cpu_operator_cost;
|
|||||||
extern Cost disable_cost;
|
extern Cost disable_cost;
|
||||||
extern bool enable_seqscan;
|
extern bool enable_seqscan;
|
||||||
extern bool enable_indexscan;
|
extern bool enable_indexscan;
|
||||||
|
extern bool enable_bitmapscan;
|
||||||
extern bool enable_tidscan;
|
extern bool enable_tidscan;
|
||||||
extern bool enable_sort;
|
extern bool enable_sort;
|
||||||
extern bool enable_hashagg;
|
extern bool enable_hashagg;
|
||||||
@ -53,8 +54,10 @@ extern double clamp_row_est(double nrows);
|
|||||||
extern void cost_seqscan(Path *path, Query *root, RelOptInfo *baserel);
|
extern void cost_seqscan(Path *path, Query *root, RelOptInfo *baserel);
|
||||||
extern void cost_index(IndexPath *path, Query *root, IndexOptInfo *index,
|
extern void cost_index(IndexPath *path, Query *root, IndexOptInfo *index,
|
||||||
List *indexQuals, bool is_injoin);
|
List *indexQuals, bool is_injoin);
|
||||||
extern void cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
extern void cost_bitmap_heap_scan(Path *path, Query *root, RelOptInfo *baserel,
|
||||||
Node *bitmapqual, bool is_injoin);
|
Path *bitmapqual, bool is_injoin);
|
||||||
|
extern void cost_bitmap_and_node(BitmapAndPath *path, Query *root);
|
||||||
|
extern void cost_bitmap_or_node(BitmapOrPath *path, Query *root);
|
||||||
extern void cost_tidscan(Path *path, Query *root,
|
extern void cost_tidscan(Path *path, Query *root,
|
||||||
RelOptInfo *baserel, List *tideval);
|
RelOptInfo *baserel, List *tideval);
|
||||||
extern void cost_subqueryscan(Path *path, RelOptInfo *baserel);
|
extern void cost_subqueryscan(Path *path, RelOptInfo *baserel);
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
|
||||||
* Portions Copyright (c) 1994, Regents of the University of California
|
* Portions Copyright (c) 1994, Regents of the University of California
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.58 2005/04/19 22:35:18 tgl Exp $
|
* $PostgreSQL: pgsql/src/include/optimizer/pathnode.h,v 1.59 2005/04/21 19:18:13 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
@ -35,7 +35,13 @@ extern IndexPath *create_index_path(Query *root,
|
|||||||
ScanDirection indexscandir);
|
ScanDirection indexscandir);
|
||||||
extern BitmapHeapPath *create_bitmap_heap_path(Query *root,
|
extern BitmapHeapPath *create_bitmap_heap_path(Query *root,
|
||||||
RelOptInfo *rel,
|
RelOptInfo *rel,
|
||||||
Node *bitmapqual);
|
Path *bitmapqual);
|
||||||
|
extern BitmapAndPath *create_bitmap_and_path(Query *root,
|
||||||
|
RelOptInfo *rel,
|
||||||
|
List *bitmapquals);
|
||||||
|
extern BitmapOrPath *create_bitmap_or_path(Query *root,
|
||||||
|
RelOptInfo *rel,
|
||||||
|
List *bitmapquals);
|
||||||
extern TidPath *create_tidscan_path(Query *root, RelOptInfo *rel,
|
extern TidPath *create_tidscan_path(Query *root, RelOptInfo *rel,
|
||||||
List *tideval);
|
List *tideval);
|
||||||
extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths);
|
extern AppendPath *create_append_path(RelOptInfo *rel, List *subpaths);
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
|
SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
|
||||||
name | setting
|
name | setting
|
||||||
------------------+---------
|
-------------------+---------
|
||||||
|
enable_bitmapscan | on
|
||||||
enable_hashagg | on
|
enable_hashagg | on
|
||||||
enable_hashjoin | on
|
enable_hashjoin | on
|
||||||
enable_indexscan | on
|
enable_indexscan | on
|
||||||
@ -9,7 +10,7 @@ SELECT name, setting FROM pg_settings WHERE name LIKE 'enable%';
|
|||||||
enable_seqscan | on
|
enable_seqscan | on
|
||||||
enable_sort | on
|
enable_sort | on
|
||||||
enable_tidscan | on
|
enable_tidscan | on
|
||||||
(8 rows)
|
(9 rows)
|
||||||
|
|
||||||
CREATE TABLE foo2(fooid int, f2 int);
|
CREATE TABLE foo2(fooid int, f2 int);
|
||||||
INSERT INTO foo2 VALUES(1, 11);
|
INSERT INTO foo2 VALUES(1, 11);
|
||||||
|
Reference in New Issue
Block a user