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

Commit6c1d466

Browse files
committed
Finish implementation of hashed aggregation. Add enable_hashagg GUC
parameter to allow it to be forced off for comparison purposes.Add ORDER BY clauses to a bunch of regression test queries that willotherwise produce randomly-ordered output in the new regime.
1 parent2676e11 commit6c1d466

25 files changed

+457
-190
lines changed

‎doc/src/sgml/runtime.sgml

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.156 2002/11/15 03:22:30 momjian Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/runtime.sgml,v 1.157 2002/11/21 00:42:18 tgl Exp $
33
-->
44

55
<Chapter Id="runtime">
@@ -670,6 +670,17 @@ env PGOPTIONS='-c geqo=off' psql
670670
</listitem>
671671
</varlistentry>
672672

673+
<varlistentry>
674+
<term><varname>ENABLE_HASHAGG</varname> (<type>boolean</type>)</term>
675+
<listitem>
676+
<para>
677+
Enables or disables the query planner's use of hashed aggregation
678+
plan types. The default is on. This is used for debugging the query
679+
planner.
680+
</para>
681+
</listitem>
682+
</varlistentry>
683+
673684
<varlistentry>
674685
<term><varname>ENABLE_HASHJOIN</varname> (<type>boolean</type>)</term>
675686
<listitem>

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

Lines changed: 97 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@
4242
* Portions Copyright (c) 1994, Regents of the University of California
4343
*
4444
* IDENTIFICATION
45-
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.90 2002/09/04 20:31:20 momjian Exp $
45+
* $Header: /cvsroot/pgsql/src/backend/optimizer/path/costsize.c,v 1.91 2002/11/21 00:42:19 tgl Exp $
4646
*
4747
*-------------------------------------------------------------------------
4848
*/
@@ -79,6 +79,7 @@ boolenable_seqscan = true;
7979
boolenable_indexscan= true;
8080
boolenable_tidscan= true;
8181
boolenable_sort= true;
82+
boolenable_hashagg= true;
8283
boolenable_nestloop= true;
8384
boolenable_mergejoin= true;
8485
boolenable_hashjoin= true;
@@ -423,10 +424,8 @@ cost_functionscan(Path *path, Query *root, RelOptInfo *baserel)
423424

424425
/*
425426
* cost_sort
426-
* Determines and returns the cost of sorting a relation.
427-
*
428-
* The cost of supplying the input data is NOT included; the caller should
429-
* add that cost to both startup and total costs returned from this routine!
427+
* Determines and returns the cost of sorting a relation, including
428+
* the cost of reading the input data.
430429
*
431430
* If the total volume of data to sort is less than SortMem, we will do
432431
* an in-memory sort, which requires no I/O and about t*log2(t) tuple
@@ -449,19 +448,22 @@ cost_functionscan(Path *path, Query *root, RelOptInfo *baserel)
449448
* the right ballpark in most cases.
450449
*
451450
* 'pathkeys' is a list of sort keys
451+
* 'input_cost' is the total cost for reading the input data
452452
* 'tuples' is the number of tuples in the relation
453453
* 'width' is the average tuple width in bytes
454454
*
455455
* NOTE: some callers currently pass NIL for pathkeys because they
456456
* can't conveniently supply the sort keys. Since this routine doesn't
457457
* currently do anything with pathkeys anyway, that doesn't matter...
458458
* but if it ever does, it should react gracefully to lack of key data.
459+
* (Actually, the thing we'd most likely be interested in is just the number
460+
* of sort keys, which all callers *could* supply.)
459461
*/
460462
void
461463
cost_sort(Path*path,Query*root,
462-
List*pathkeys,doubletuples,intwidth)
464+
List*pathkeys,Costinput_cost,doubletuples,intwidth)
463465
{
464-
Coststartup_cost=0;
466+
Coststartup_cost=input_cost;
465467
Costrun_cost=0;
466468
doublenbytes=relation_byte_size(tuples,width);
467469
longsortmembytes=SortMem*1024L;
@@ -511,6 +513,92 @@ cost_sort(Path *path, Query *root,
511513
path->total_cost=startup_cost+run_cost;
512514
}
513515

516+
/*
517+
* cost_agg
518+
*Determines and returns the cost of performing an Agg plan node,
519+
*including the cost of its input.
520+
*
521+
* Note: when aggstrategy == AGG_SORTED, caller must ensure that input costs
522+
* are for appropriately-sorted input.
523+
*/
524+
void
525+
cost_agg(Path*path,Query*root,
526+
AggStrategyaggstrategy,intnumAggs,
527+
intnumGroupCols,doublenumGroups,
528+
Costinput_startup_cost,Costinput_total_cost,
529+
doubleinput_tuples)
530+
{
531+
Coststartup_cost;
532+
Costtotal_cost;
533+
534+
/*
535+
* We charge one cpu_operator_cost per aggregate function per input
536+
* tuple, and another one per output tuple (corresponding to transfn
537+
* and finalfn calls respectively). If we are grouping, we charge an
538+
* additional cpu_operator_cost per grouping column per input tuple
539+
* for grouping comparisons.
540+
*
541+
* We will produce a single output tuple if not grouping,
542+
* and a tuple per group otherwise.
543+
*/
544+
if (aggstrategy==AGG_PLAIN)
545+
{
546+
startup_cost=input_total_cost;
547+
startup_cost+=cpu_operator_cost* (input_tuples+1)*numAggs;
548+
/* we aren't grouping */
549+
total_cost=startup_cost;
550+
}
551+
elseif (aggstrategy==AGG_SORTED)
552+
{
553+
/* Here we are able to deliver output on-the-fly */
554+
startup_cost=input_startup_cost;
555+
total_cost=input_total_cost;
556+
total_cost+=cpu_operator_cost* (input_tuples+numGroups)*numAggs;
557+
total_cost+=cpu_operator_cost*input_tuples*numGroupCols;
558+
}
559+
else
560+
{
561+
/* must be AGG_HASHED */
562+
startup_cost=input_total_cost;
563+
startup_cost+=cpu_operator_cost*input_tuples*numAggs;
564+
startup_cost+=cpu_operator_cost*input_tuples*numGroupCols;
565+
total_cost=startup_cost;
566+
total_cost+=cpu_operator_cost*numGroups*numAggs;
567+
}
568+
569+
path->startup_cost=startup_cost;
570+
path->total_cost=total_cost;
571+
}
572+
573+
/*
574+
* cost_group
575+
*Determines and returns the cost of performing a Group plan node,
576+
*including the cost of its input.
577+
*
578+
* Note: caller must ensure that input costs are for appropriately-sorted
579+
* input.
580+
*/
581+
void
582+
cost_group(Path*path,Query*root,
583+
intnumGroupCols,doublenumGroups,
584+
Costinput_startup_cost,Costinput_total_cost,
585+
doubleinput_tuples)
586+
{
587+
Coststartup_cost;
588+
Costtotal_cost;
589+
590+
startup_cost=input_startup_cost;
591+
total_cost=input_total_cost;
592+
593+
/*
594+
* Charge one cpu_operator_cost per comparison per input tuple. We
595+
* assume all columns get compared at most of the tuples.
596+
*/
597+
total_cost+=cpu_operator_cost*input_tuples*numGroupCols;
598+
599+
path->startup_cost=startup_cost;
600+
path->total_cost=total_cost;
601+
}
514602

515603
/*
516604
* cost_nestloop
@@ -658,10 +746,10 @@ cost_mergejoin(Path *path, Query *root,
658746
*/
659747
if (outersortkeys)/* do we need to sort outer? */
660748
{
661-
startup_cost+=outer_path->total_cost;
662749
cost_sort(&sort_path,
663750
root,
664751
outersortkeys,
752+
outer_path->total_cost,
665753
outer_path->parent->rows,
666754
outer_path->parent->width);
667755
startup_cost+=sort_path.startup_cost;
@@ -677,10 +765,10 @@ cost_mergejoin(Path *path, Query *root,
677765

678766
if (innersortkeys)/* do we need to sort inner? */
679767
{
680-
startup_cost+=inner_path->total_cost;
681768
cost_sort(&sort_path,
682769
root,
683770
innersortkeys,
771+
inner_path->total_cost,
684772
inner_path->parent->rows,
685773
inner_path->parent->width);
686774
startup_cost+=sort_path.startup_cost;

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

Lines changed: 35 additions & 29 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.123 2002/11/19 23:21:58 tgl Exp $
13+
* $Header: /cvsroot/pgsql/src/backend/optimizer/plan/createplan.c,v 1.124 2002/11/21 00:42:19 tgl Exp $
1414
*
1515
*-------------------------------------------------------------------------
1616
*/
@@ -1573,9 +1573,11 @@ make_sort(Query *root, List *tlist, Plan *lefttree, int keycount)
15731573

15741574
copy_plan_costsize(plan,lefttree);/* only care about copying size */
15751575
cost_sort(&sort_path,root,NIL,
1576-
lefttree->plan_rows,lefttree->plan_width);
1577-
plan->startup_cost=sort_path.startup_cost+lefttree->total_cost;
1578-
plan->total_cost=sort_path.total_cost+lefttree->total_cost;
1576+
lefttree->total_cost,
1577+
lefttree->plan_rows,
1578+
lefttree->plan_width);
1579+
plan->startup_cost=sort_path.startup_cost;
1580+
plan->total_cost=sort_path.total_cost;
15791581
plan->state= (EState*)NULL;
15801582
plan->targetlist=tlist;
15811583
plan->qual=NIL;
@@ -1683,39 +1685,39 @@ make_material(List *tlist, Plan *lefttree)
16831685
}
16841686

16851687
Agg*
1686-
make_agg(List*tlist,List*qual,AggStrategyaggstrategy,
1687-
intngrp,AttrNumber*grpColIdx,longnumGroups,intnumAggs,
1688+
make_agg(Query*root,List*tlist,List*qual,
1689+
AggStrategyaggstrategy,
1690+
intnumGroupCols,AttrNumber*grpColIdx,
1691+
longnumGroups,intnumAggs,
16881692
Plan*lefttree)
16891693
{
16901694
Agg*node=makeNode(Agg);
16911695
Plan*plan=&node->plan;
1696+
Pathagg_path;/* dummy for result of cost_agg */
16921697

16931698
node->aggstrategy=aggstrategy;
1694-
node->numCols=ngrp;
1699+
node->numCols=numGroupCols;
16951700
node->grpColIdx=grpColIdx;
16961701
node->numGroups=numGroups;
16971702

1698-
copy_plan_costsize(plan,lefttree);
1699-
1700-
/*
1701-
* Charge one cpu_operator_cost per aggregate function per input
1702-
* tuple.
1703-
*/
1704-
plan->total_cost+=cpu_operator_cost*plan->plan_rows*numAggs;
1703+
copy_plan_costsize(plan,lefttree);/* only care about copying size */
1704+
cost_agg(&agg_path,root,
1705+
aggstrategy,numAggs,
1706+
numGroupCols,numGroups,
1707+
lefttree->startup_cost,
1708+
lefttree->total_cost,
1709+
lefttree->plan_rows);
1710+
plan->startup_cost=agg_path.startup_cost;
1711+
plan->total_cost=agg_path.total_cost;
17051712

17061713
/*
17071714
* We will produce a single output tuple if not grouping,
17081715
* and a tuple per group otherwise.
17091716
*/
17101717
if (aggstrategy==AGG_PLAIN)
1711-
{
17121718
plan->plan_rows=1;
1713-
plan->startup_cost=plan->total_cost;
1714-
}
17151719
else
1716-
{
17171720
plan->plan_rows=numGroups;
1718-
}
17191721

17201722
plan->state= (EState*)NULL;
17211723
plan->qual=qual;
@@ -1727,22 +1729,28 @@ make_agg(List *tlist, List *qual, AggStrategy aggstrategy,
17271729
}
17281730

17291731
Group*
1730-
make_group(List*tlist,
1731-
intngrp,
1732+
make_group(Query*root,
1733+
List*tlist,
1734+
intnumGroupCols,
17321735
AttrNumber*grpColIdx,
17331736
doublenumGroups,
17341737
Plan*lefttree)
17351738
{
17361739
Group*node=makeNode(Group);
17371740
Plan*plan=&node->plan;
1741+
Pathgroup_path;/* dummy for result of cost_group */
17381742

1739-
copy_plan_costsize(plan,lefttree);
1743+
node->numCols=numGroupCols;
1744+
node->grpColIdx=grpColIdx;
17401745

1741-
/*
1742-
* Charge one cpu_operator_cost per comparison per input tuple. We
1743-
* assume all columns get compared at most of the tuples.
1744-
*/
1745-
plan->total_cost+=cpu_operator_cost*plan->plan_rows*ngrp;
1746+
copy_plan_costsize(plan,lefttree);/* only care about copying size */
1747+
cost_group(&group_path,root,
1748+
numGroupCols,numGroups,
1749+
lefttree->startup_cost,
1750+
lefttree->total_cost,
1751+
lefttree->plan_rows);
1752+
plan->startup_cost=group_path.startup_cost;
1753+
plan->total_cost=group_path.total_cost;
17461754

17471755
/* One output tuple per estimated result group */
17481756
plan->plan_rows=numGroups;
@@ -1752,8 +1760,6 @@ make_group(List *tlist,
17521760
plan->targetlist=tlist;
17531761
plan->lefttree=lefttree;
17541762
plan->righttree= (Plan*)NULL;
1755-
node->numCols=ngrp;
1756-
node->grpColIdx=grpColIdx;
17571763

17581764
returnnode;
17591765
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp