Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit14c7fba

Browse files
committed
Rethink original decision to use AND/OR Expr nodes to represent bitmap
logic operations during planning. Seems cleaner to create two new Pathnode types, instead --- this avoids duplication of cost-estimation code.Also, create an enable_bitmapscan GUC parameter to control use of bitmapplans.
1 parentc6221db commit14c7fba

File tree

16 files changed

+338
-193
lines changed

16 files changed

+338
-193
lines changed

‎doc/src/sgml/runtime.sgml

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.313 2005/04/08 00:59:57 neilc Exp $
2+
$PostgreSQL: pgsql/doc/src/sgml/runtime.sgml,v 1.314 2005/04/21 19:18:12 tgl Exp $
33
-->
44

55
<chapter Id="runtime">
@@ -1768,6 +1768,22 @@ archive_command = 'copy "%p" /mnt/server/archivedir/"%f"' # Windows
17681768
</para>
17691769

17701770
<variablelist>
1771+
<varlistentry id="guc-enable-bitmapscan" xreflabel="enable_bitmapscan">
1772+
<term><varname>enable_bitmapscan</varname> (<type>boolean</type>)</term>
1773+
<indexterm>
1774+
<primary>bitmap scan</primary>
1775+
</indexterm>
1776+
<indexterm>
1777+
<primary><varname>enable_bitmapscan</> configuration parameter</primary>
1778+
</indexterm>
1779+
<listitem>
1780+
<para>
1781+
Enables or disables the query planner's use of bitmap-scan plan
1782+
types. The default is on.
1783+
</para>
1784+
</listitem>
1785+
</varlistentry>
1786+
17711787
<varlistentry id="guc-enable-hashagg" xreflabel="enable_hashagg">
17721788
<term><varname>enable_hashagg</varname> (<type>boolean</type>)</term>
17731789
<indexterm>
@@ -4094,7 +4110,7 @@ plruby.bar = true # generates error, unknown class name
40944110

40954111
<row>
40964112
<entry>
4097-
<option>-fi</option>, <option>-fh</option>,
4113+
<option>-fb</option>, <option>-fh</option>, <option>-fi</option>,
40984114
<option>-fm</option>, <option>-fn</option>,
40994115
<option>-fs</option>, <option>-ft</option><footnote
41004116
id="fn.runtime-config-short">
@@ -4111,8 +4127,9 @@ $ <userinput>postmaster -o '-S 1024 -s'</userinput>
41114127
</footnote>
41124128
</entry>
41134129
<entry>
4114-
<literal>enable_indexscan = off</>,
4130+
<literal>enable_bitmapscan = off</>,
41154131
<literal>enable_hashjoin = off</>,
4132+
<literal>enable_indexscan = off</>,
41164133
<literal>enable_mergejoin = off</>,
41174134
<literal>enable_nestloop = off</>,
41184135
<literal>enable_seqscan = off</>,

‎src/backend/nodes/outfuncs.c

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.248 2005/04/2102:28:01 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/nodes/outfuncs.c,v 1.249 2005/04/2119:18:12 tgl Exp $
1212
*
1313
* NOTES
1414
* Every node type that can appear in stored rules' parsetrees *must*
@@ -1041,6 +1041,28 @@ _outBitmapHeapPath(StringInfo str, BitmapHeapPath *node)
10411041
WRITE_FLOAT_FIELD(rows,"%.0f");
10421042
}
10431043

1044+
staticvoid
1045+
_outBitmapAndPath(StringInfostr,BitmapAndPath*node)
1046+
{
1047+
WRITE_NODE_TYPE("BITMAPANDPATH");
1048+
1049+
_outPathInfo(str, (Path*)node);
1050+
1051+
WRITE_NODE_FIELD(bitmapquals);
1052+
WRITE_FLOAT_FIELD(bitmapselectivity,"%.4f");
1053+
}
1054+
1055+
staticvoid
1056+
_outBitmapOrPath(StringInfostr,BitmapOrPath*node)
1057+
{
1058+
WRITE_NODE_TYPE("BITMAPORPATH");
1059+
1060+
_outPathInfo(str, (Path*)node);
1061+
1062+
WRITE_NODE_FIELD(bitmapquals);
1063+
WRITE_FLOAT_FIELD(bitmapselectivity,"%.4f");
1064+
}
1065+
10441066
staticvoid
10451067
_outTidPath(StringInfostr,TidPath*node)
10461068
{
@@ -1853,6 +1875,12 @@ _outNode(StringInfo str, void *obj)
18531875
caseT_BitmapHeapPath:
18541876
_outBitmapHeapPath(str,obj);
18551877
break;
1878+
caseT_BitmapAndPath:
1879+
_outBitmapAndPath(str,obj);
1880+
break;
1881+
caseT_BitmapOrPath:
1882+
_outBitmapOrPath(str,obj);
1883+
break;
18561884
caseT_TidPath:
18571885
_outTidPath(str,obj);
18581886
break;

‎src/backend/optimizer/README

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ RelOptInfo - a relation or joined relations
255255
Path - every way to generate a RelOptInfo(sequential,index,joins)
256256
SeqScan - a plain Path node with pathtype = T_SeqScan
257257
IndexPath - index scans
258+
BitmapHeapPath - top of a bitmapped index scan
258259
TidPath - scan by CTID
259260
AppendPath - append multiple subpaths together
260261
ResultPath - a Result plan node (used for variable-free tlist or qual)

‎src/backend/optimizer/path/allpaths.c

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.126 2005/04/19 22:35:15 tgl Exp $
11+
* $PostgreSQL: pgsql/src/backend/optimizer/path/allpaths.c,v 1.127 2005/04/21 19:18:12 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -901,6 +901,12 @@ print_path(Query *root, Path *path, int indent)
901901
caseT_BitmapHeapPath:
902902
ptype="BitmapHeapScan";
903903
break;
904+
caseT_BitmapAndPath:
905+
ptype="BitmapAndPath";
906+
break;
907+
caseT_BitmapOrPath:
908+
ptype="BitmapOrPath";
909+
break;
904910
caseT_TidPath:
905911
ptype="TidScan";
906912
break;

‎src/backend/optimizer/path/costsize.c

Lines changed: 113 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@
4949
* Portions Copyright (c) 1994, Regents of the University of California
5050
*
5151
* IDENTIFICATION
52-
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.143 2005/04/2102:28:01 tgl Exp $
52+
* $PostgreSQL: pgsql/src/backend/optimizer/path/costsize.c,v 1.144 2005/04/2119:18:12 tgl Exp $
5353
*
5454
*-------------------------------------------------------------------------
5555
*/
@@ -94,6 +94,7 @@ Costdisable_cost = 100000000.0;
9494

9595
boolenable_seqscan= true;
9696
boolenable_indexscan= true;
97+
boolenable_bitmapscan= true;
9798
boolenable_tidscan= true;
9899
boolenable_sort= true;
99100
boolenable_hashagg= true;
@@ -103,7 +104,7 @@ boolenable_hashjoin = true;
103104

104105

105106
staticboolcost_qual_eval_walker(Node*node,QualCost*total);
106-
staticSelectivitycost_bitmap_qual(Node*bitmapqual,Cost*totalCost);
107+
staticvoidcost_bitmap_tree_node(Path*path,Cost*cost,Selectivity*selec);
107108
staticSelectivityapprox_selectivity(Query*root,List*quals,
108109
JoinTypejointype);
109110
staticSelectivityjoin_in_selectivity(JoinPath*path,Query*root);
@@ -292,7 +293,7 @@ cost_index(IndexPath *path, Query *root,
292293
PointerGetDatum(&indexCorrelation));
293294

294295
/*
295-
* Save amcostestimate's results for possible useby cost_bitmap_scan.
296+
* Save amcostestimate's results for possible usein bitmap scan planning.
296297
* We don't bother to save indexStartupCost or indexCorrelation, because
297298
* a bitmap scan doesn't care about either.
298299
*/
@@ -414,19 +415,19 @@ cost_index(IndexPath *path, Query *root,
414415
}
415416

416417
/*
417-
*cost_bitmap_scan
418+
*cost_bitmap_heap_scan
418419
* Determines and returns the cost of scanning a relation using a bitmap
419420
* index-then-heap plan.
420421
*
421422
* 'root' is the query root
422423
* 'baserel' is the relation to be scanned
423-
* 'bitmapqual' isan AND/ORtree of IndexPaths for the component scans
424+
* 'bitmapqual' isatree of IndexPaths, BitmapAndPaths, and BitmapOrPaths
424425
* 'is_injoin' is T if we are considering using the scan as the inside
425426
*of a nestloop join (hence, some of the quals are join clauses)
426427
*/
427428
void
428-
cost_bitmap_scan(Path*path,Query*root,RelOptInfo*baserel,
429-
Node*bitmapqual,boolis_injoin)
429+
cost_bitmap_heap_scan(Path*path,Query*root,RelOptInfo*baserel,
430+
Path*bitmapqual,boolis_injoin)
430431
{
431432
Coststartup_cost=0;
432433
Costrun_cost=0;
@@ -443,15 +444,14 @@ cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
443444
Assert(baserel->relid>0);
444445
Assert(baserel->rtekind==RTE_RELATION);
445446

446-
if (!enable_indexscan)/* XXX use a separate enable flag? */
447+
if (!enable_bitmapscan)
447448
startup_cost+=disable_cost;
448449

449450
/*
450-
*Estimate total cost of obtaining the bitmap, as well as its total
451+
*Fetch total cost of obtaining the bitmap, as well as its total
451452
* selectivity.
452453
*/
453-
indexTotalCost=0;
454-
indexSelectivity=cost_bitmap_qual(bitmapqual,&indexTotalCost);
454+
cost_bitmap_tree_node(bitmapqual,&indexTotalCost,&indexSelectivity);
455455

456456
startup_cost+=indexTotalCost;
457457

@@ -497,82 +497,120 @@ cost_bitmap_scan(Path *path, Query *root, RelOptInfo *baserel,
497497
}
498498

499499
/*
500-
* cost_bitmap_qual
501-
*Recursively examine the AND/OR/IndexPath tree for a bitmap scan
502-
*
503-
* Total execution costs are added to *totalCost (so caller must be sure
504-
* to initialize that to zero). Estimated total selectivity of the bitmap
505-
* is returned as the function result.
500+
* cost_bitmap_tree_node
501+
*Extract cost and selectivity from a bitmap tree node (index/and/or)
506502
*/
507-
staticSelectivity
508-
cost_bitmap_qual(Node*bitmapqual,Cost*totalCost)
503+
staticvoid
504+
cost_bitmap_tree_node(Path*path,Cost*cost,Selectivity*selec)
509505
{
510-
Selectivityresult;
511-
Selectivitysubresult;
512-
ListCell*l;
513-
514-
if (and_clause(bitmapqual))
506+
if (IsA(path,IndexPath))
515507
{
516-
/*
517-
* We estimate AND selectivity on the assumption that the inputs
518-
* are independent. This is probably often wrong, but we don't
519-
* have the info to do better.
520-
*
521-
* The runtime cost of the BitmapAnd itself is estimated at 100x
522-
* cpu_operator_cost for each tbm_intersect needed. Probably too
523-
* small, definitely too simplistic?
524-
*
525-
* This must agree with make_bitmap_and in createplan.c.
526-
*/
527-
result=1.0;
528-
foreach(l, ((BoolExpr*)bitmapqual)->args)
529-
{
530-
subresult=cost_bitmap_qual((Node*)lfirst(l),totalCost);
531-
result *=subresult;
532-
if (l!=list_head(((BoolExpr*)bitmapqual)->args))
533-
*totalCost+=100.0*cpu_operator_cost;
534-
}
508+
*cost= ((IndexPath*)path)->indextotalcost;
509+
*selec= ((IndexPath*)path)->indexselectivity;
535510
}
536-
elseif (or_clause(bitmapqual))
511+
elseif (IsA(path,BitmapAndPath))
537512
{
538-
/*
539-
* We estimate OR selectivity on the assumption that the inputs
540-
* are non-overlapping, since that's often the case in "x IN (list)"
541-
* type situations. Of course, we clamp to 1.0 at the end.
542-
*
543-
* The runtime cost of the BitmapOr itself is estimated at 100x
544-
* cpu_operator_cost for each tbm_union needed. Probably too
545-
* small, definitely too simplistic? We are aware that the tbm_unions
546-
* are optimized out when the inputs are BitmapIndexScans.
547-
*
548-
* This must agree with make_bitmap_or in createplan.c.
549-
*/
550-
result=0.0;
551-
foreach(l, ((BoolExpr*)bitmapqual)->args)
552-
{
553-
subresult=cost_bitmap_qual((Node*)lfirst(l),totalCost);
554-
result+=subresult;
555-
if (l!=list_head(((BoolExpr*)bitmapqual)->args)&&
556-
!IsA((Node*)lfirst(l),IndexPath))
557-
*totalCost+=100.0*cpu_operator_cost;
558-
}
559-
result=Min(result,1.0);
513+
*cost=path->total_cost;
514+
*selec= ((BitmapAndPath*)path)->bitmapselectivity;
560515
}
561-
elseif (IsA(bitmapqual,IndexPath))
516+
elseif (IsA(path,BitmapOrPath))
562517
{
563-
IndexPath*ipath= (IndexPath*)bitmapqual;
564-
565-
/* this must agree with create_bitmap_subplan in createplan.c */
566-
*totalCost+=ipath->indextotalcost;
567-
result=ipath->indexselectivity;
518+
*cost=path->total_cost;
519+
*selec= ((BitmapOrPath*)path)->bitmapselectivity;
568520
}
569521
else
522+
elog(ERROR,"unrecognized node type: %d",nodeTag(path));
523+
}
524+
525+
/*
526+
* cost_bitmap_and_node
527+
*Estimate the cost of a BitmapAnd node
528+
*
529+
* Note that this considers only the costs of index scanning and bitmap
530+
* creation, not the eventual heap access. In that sense the object isn't
531+
* truly a Path, but it has enough path-like properties (costs in particular)
532+
* to warrant treating it as one.
533+
*/
534+
void
535+
cost_bitmap_and_node(BitmapAndPath*path,Query*root)
536+
{
537+
CosttotalCost;
538+
Selectivityselec;
539+
ListCell*l;
540+
541+
/*
542+
* We estimate AND selectivity on the assumption that the inputs
543+
* are independent. This is probably often wrong, but we don't
544+
* have the info to do better.
545+
*
546+
* The runtime cost of the BitmapAnd itself is estimated at 100x
547+
* cpu_operator_cost for each tbm_intersect needed. Probably too
548+
* small, definitely too simplistic?
549+
*/
550+
totalCost=0.0;
551+
selec=1.0;
552+
foreach(l,path->bitmapquals)
570553
{
571-
elog(ERROR,"unrecognized node type: %d",nodeTag(bitmapqual));
572-
result=0.0;/* keep compiler quiet */
554+
Path*subpath= (Path*)lfirst(l);
555+
CostsubCost;
556+
Selectivitysubselec;
557+
558+
cost_bitmap_tree_node(subpath,&subCost,&subselec);
559+
560+
selec *=subselec;
561+
562+
totalCost+=subCost;
563+
if (l!=list_head(path->bitmapquals))
564+
totalCost+=100.0*cpu_operator_cost;
573565
}
566+
path->bitmapselectivity=selec;
567+
path->path.startup_cost=totalCost;
568+
path->path.total_cost=totalCost;
569+
}
570+
571+
/*
572+
* cost_bitmap_or_node
573+
*Estimate the cost of a BitmapOr node
574+
*
575+
* See comments for cost_bitmap_and_node.
576+
*/
577+
void
578+
cost_bitmap_or_node(BitmapOrPath*path,Query*root)
579+
{
580+
CosttotalCost;
581+
Selectivityselec;
582+
ListCell*l;
583+
584+
/*
585+
* We estimate OR selectivity on the assumption that the inputs
586+
* are non-overlapping, since that's often the case in "x IN (list)"
587+
* type situations. Of course, we clamp to 1.0 at the end.
588+
*
589+
* The runtime cost of the BitmapOr itself is estimated at 100x
590+
* cpu_operator_cost for each tbm_union needed. Probably too
591+
* small, definitely too simplistic? We are aware that the tbm_unions
592+
* are optimized out when the inputs are BitmapIndexScans.
593+
*/
594+
totalCost=0.0;
595+
selec=0.0;
596+
foreach(l,path->bitmapquals)
597+
{
598+
Path*subpath= (Path*)lfirst(l);
599+
CostsubCost;
600+
Selectivitysubselec;
574601

575-
returnresult;
602+
cost_bitmap_tree_node(subpath,&subCost,&subselec);
603+
604+
selec+=subselec;
605+
606+
totalCost+=subCost;
607+
if (l!=list_head(path->bitmapquals)&&
608+
!IsA(subpath,IndexPath))
609+
totalCost+=100.0*cpu_operator_cost;
610+
}
611+
path->bitmapselectivity=Min(selec,1.0);
612+
path->path.startup_cost=totalCost;
613+
path->path.total_cost=totalCost;
576614
}
577615

578616
/*

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp