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

Commitb60be3f

Browse files
committed
Add an at-least-marginally-plausible method of estimating the number
of groups produced by GROUP BY. This improves the accuracy of planningestimates for grouped subselects, and is needed to check whether ahashed aggregation plan risks memory overflow.
1 parent54cb1db commitb60be3f

File tree

11 files changed

+454
-75
lines changed

11 files changed

+454
-75
lines changed

‎src/backend/executor/nodeAgg.c

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
* Portions Copyright (c) 1994, Regents of the University of California
4646
*
4747
* IDENTIFICATION
48-
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.95 2002/11/13 00:39:47 momjian Exp $
48+
* $Header: /cvsroot/pgsql/src/backend/executor/nodeAgg.c,v 1.96 2002/11/19 23:21:57 tgl Exp $
4949
*
5050
*-------------------------------------------------------------------------
5151
*/
@@ -619,6 +619,9 @@ lookup_hash_entry(Agg *node, TupleTableSlot *slot)
619619
Datumattr;
620620
boolisNull;
621621

622+
/* rotate hashkey left 1 bit at each step */
623+
hashkey= (hashkey <<1) | ((hashkey&0x80000000) ?1 :0);
624+
622625
attr=heap_getattr(tuple,att,tupdesc,&isNull);
623626
if (isNull)
624627
continue;/* treat nulls as having hash key 0 */

‎src/backend/nodes/copyfuncs.c

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* Portions Copyright (c) 1994, Regents of the University of California
1616
*
1717
* IDENTIFICATION
18-
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.218 2002/11/15 02:50:06 momjian Exp $
18+
* $Header: /cvsroot/pgsql/src/backend/nodes/copyfuncs.c,v 1.219 2002/11/19 23:21:58 tgl Exp $
1919
*
2020
*-------------------------------------------------------------------------
2121
*/
@@ -1865,8 +1865,8 @@ _copyQuery(Query *from)
18651865

18661866
/*
18671867
* We do not copy the planner internal fields: base_rel_list,
1868-
* other_rel_list, join_rel_list, equi_key_list, query_pathkeys. Not
1869-
* entirely clear if this is right?
1868+
* other_rel_list, join_rel_list, equi_key_list, query_pathkeys,
1869+
*hasJoinRTEs. Notentirely clear if this is right?
18701870
*/
18711871

18721872
returnnewnode;

‎src/backend/nodes/equalfuncs.c

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
* Portions Copyright (c) 1994, Regents of the University of California
2121
*
2222
* IDENTIFICATION
23-
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.164 2002/11/15 02:50:06 momjian Exp $
23+
* $Header: /cvsroot/pgsql/src/backend/nodes/equalfuncs.c,v 1.165 2002/11/19 23:21:58 tgl Exp $
2424
*
2525
*-------------------------------------------------------------------------
2626
*/
@@ -628,9 +628,9 @@ _equalQuery(Query *a, Query *b)
628628

629629
/*
630630
* We do not check the internal-to-the-planner fields: base_rel_list,
631-
* other_rel_list, join_rel_list, equi_key_list, query_pathkeys. They
632-
* might not be set yet, and in any case they should be derivable from
633-
* the other fields.
631+
* other_rel_list, join_rel_list, equi_key_list, query_pathkeys,
632+
*hasJoinRTEs. Theymight not be set yet, and in any case they should
633+
*be derivable fromthe other fields.
634634
*/
635635
return true;
636636
}

‎src/backend/optimizer/plan/createplan.c

Lines changed: 17 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
*
1111
*
1212
* IDENTIFICATION
13-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.122 2002/11/15 02:36:53 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.123 2002/11/19 23:21:58 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1684,30 +1684,28 @@ make_material(List *tlist, Plan *lefttree)
16841684

16851685
Agg*
16861686
make_agg(List*tlist,List*qual,AggStrategyaggstrategy,
1687-
intngrp,AttrNumber*grpColIdx,Plan*lefttree)
1687+
intngrp,AttrNumber*grpColIdx,longnumGroups,intnumAggs,
1688+
Plan*lefttree)
16881689
{
16891690
Agg*node=makeNode(Agg);
16901691
Plan*plan=&node->plan;
16911692

16921693
node->aggstrategy=aggstrategy;
16931694
node->numCols=ngrp;
16941695
node->grpColIdx=grpColIdx;
1696+
node->numGroups=numGroups;
16951697

16961698
copy_plan_costsize(plan,lefttree);
16971699

16981700
/*
16991701
* Charge one cpu_operator_cost per aggregate function per input
17001702
* tuple.
17011703
*/
1702-
plan->total_cost+=cpu_operator_cost*plan->plan_rows*
1703-
(length(pull_agg_clause((Node*)tlist))+
1704-
length(pull_agg_clause((Node*)qual)));
1704+
plan->total_cost+=cpu_operator_cost*plan->plan_rows*numAggs;
17051705

17061706
/*
17071707
* We will produce a single output tuple if not grouping,
1708-
* and a tuple per group otherwise. For now, estimate the number of
1709-
* groups as 10% of the number of tuples --- bogus, but how to do
1710-
* better?
1708+
* and a tuple per group otherwise.
17111709
*/
17121710
if (aggstrategy==AGG_PLAIN)
17131711
{
@@ -1716,10 +1714,7 @@ make_agg(List *tlist, List *qual, AggStrategy aggstrategy,
17161714
}
17171715
else
17181716
{
1719-
plan->plan_rows *=0.1;
1720-
if (plan->plan_rows<1)
1721-
plan->plan_rows=1;
1722-
node->numGroups= (long)plan->plan_rows;
1717+
plan->plan_rows=numGroups;
17231718
}
17241719

17251720
plan->state= (EState*)NULL;
@@ -1735,6 +1730,7 @@ Group *
17351730
make_group(List*tlist,
17361731
intngrp,
17371732
AttrNumber*grpColIdx,
1733+
doublenumGroups,
17381734
Plan*lefttree)
17391735
{
17401736
Group*node=makeNode(Group);
@@ -1748,13 +1744,8 @@ make_group(List *tlist,
17481744
*/
17491745
plan->total_cost+=cpu_operator_cost*plan->plan_rows*ngrp;
17501746

1751-
/*
1752-
* Estimate the number of groups as 10% of the number of tuples
1753-
* --- bogus, but how to do better?
1754-
*/
1755-
plan->plan_rows *=0.1;
1756-
if (plan->plan_rows<1)
1757-
plan->plan_rows=1;
1747+
/* One output tuple per estimated result group */
1748+
plan->plan_rows=numGroups;
17581749

17591750
plan->state= (EState*)NULL;
17601751
plan->qual=NULL;
@@ -1786,17 +1777,16 @@ make_unique(List *tlist, Plan *lefttree, List *distinctList)
17861777

17871778
/*
17881779
* Charge one cpu_operator_cost per comparison per input tuple. We
1789-
* assume all columns get compared at most of the tuples.
1780+
* assume all columns get compared at most of the tuples. (XXX probably
1781+
* this is an overestimate.)
17901782
*/
17911783
plan->total_cost+=cpu_operator_cost*plan->plan_rows*numCols;
17921784

17931785
/*
1794-
* As for Group, we make the unsupported assumption that there will be
1795-
* 10% as many tuples out as in.
1786+
* plan->plan_rows is left as a copy of the input subplan's plan_rows;
1787+
* ie, we assume the filter removes nothing. The caller must alter this
1788+
* if he has a better idea.
17961789
*/
1797-
plan->plan_rows *=0.1;
1798-
if (plan->plan_rows<1)
1799-
plan->plan_rows=1;
18001790

18011791
plan->state= (EState*)NULL;
18021792
plan->targetlist=tlist;
@@ -1850,8 +1840,8 @@ make_setop(SetOpCmd cmd, List *tlist, Plan *lefttree,
18501840
plan->total_cost+=cpu_operator_cost*plan->plan_rows*numCols;
18511841

18521842
/*
1853-
*As for Group, wemake the unsupported assumption that there will be
1854-
*10% as manytuples out as in.
1843+
*Wemake the unsupported assumption that there will be 10% as many
1844+
* tuples out as in. Any way to do better?
18551845
*/
18561846
plan->plan_rows *=0.1;
18571847
if (plan->plan_rows<1)

‎src/backend/optimizer/plan/initsplan.c

Lines changed: 66 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
*
99
*
1010
* IDENTIFICATION
11-
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.75 2002/09/04 20:31:21 momjian Exp $
11+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/initsplan.c,v 1.76 2002/11/19 23:21:58 tgl Exp $
1212
*
1313
*-------------------------------------------------------------------------
1414
*/
@@ -784,6 +784,71 @@ process_implied_equality(Query *root, Node *item1, Node *item2,
784784
pull_varnos((Node*)clause));
785785
}
786786

787+
/*
788+
* vars_known_equal
789+
* Detect whether two Vars are known equal due to equijoin clauses.
790+
*
791+
* This is not completely accurate since we avoid adding redundant restriction
792+
* clauses to individual base rels (see qual_is_redundant). However, after
793+
* the implied-equality-deduction phase, it is complete for Vars of different
794+
* rels; that's sufficient for planned uses.
795+
*/
796+
bool
797+
vars_known_equal(Query*root,Var*var1,Var*var2)
798+
{
799+
Indexirel1;
800+
Indexirel2;
801+
RelOptInfo*rel1;
802+
List*restrictlist;
803+
List*itm;
804+
805+
/*
806+
* Would need more work here if we wanted to check for known equality
807+
* of general clauses: there might be multiple base rels involved.
808+
*/
809+
Assert(IsA(var1,Var));
810+
irel1=var1->varno;
811+
Assert(IsA(var2,Var));
812+
irel2=var2->varno;
813+
814+
/*
815+
* If both vars belong to same rel, we need to look at that rel's
816+
* baserestrictinfo list. If different rels, each will have a
817+
* joininfo node for the other, and we can scan either list.
818+
*/
819+
rel1=find_base_rel(root,irel1);
820+
if (irel1==irel2)
821+
restrictlist=rel1->baserestrictinfo;
822+
else
823+
{
824+
JoinInfo*joininfo=find_joininfo_node(rel1,
825+
makeListi1(irel2));
826+
827+
restrictlist=joininfo->jinfo_restrictinfo;
828+
}
829+
830+
/*
831+
* Scan to see if equality is known.
832+
*/
833+
foreach(itm,restrictlist)
834+
{
835+
RestrictInfo*restrictinfo= (RestrictInfo*)lfirst(itm);
836+
Node*left,
837+
*right;
838+
839+
if (restrictinfo->mergejoinoperator==InvalidOid)
840+
continue;/* ignore non-mergejoinable clauses */
841+
/* We now know the restrictinfo clause is a binary opclause */
842+
left= (Node*)get_leftop(restrictinfo->clause);
843+
right= (Node*)get_rightop(restrictinfo->clause);
844+
if ((equal(var1,left)&&equal(var2,right))||
845+
(equal(var2,left)&&equal(var1,right)))
846+
return true;/* found a matching clause */
847+
}
848+
849+
return false;
850+
}
851+
787852
/*
788853
* qual_is_redundant
789854
* Detect whether an implied-equality qual that turns out to be a

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp