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 @@ bool enable_seqscan = true;
7979bool enable_indexscan = true;
8080bool enable_tidscan = true;
8181bool enable_sort = true;
82+ bool enable_hashagg = true;
8283bool enable_nestloop = true;
8384bool enable_mergejoin = true;
8485bool enable_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 */
460462void
461463cost_sort (Path * path , Query * root ,
462- List * pathkeys , double tuples , int width )
464+ List * pathkeys , Cost input_cost , double tuples , int width )
463465{
464- Cost startup_cost = 0 ;
466+ Cost startup_cost = input_cost ;
465467 Cost run_cost = 0 ;
466468 double nbytes = relation_byte_size (tuples , width );
467469 long sortmembytes = 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+ AggStrategy aggstrategy , int numAggs ,
527+ int numGroupCols , double numGroups ,
528+ Cost input_startup_cost , Cost input_total_cost ,
529+ double input_tuples )
530+ {
531+ Cost startup_cost ;
532+ Cost total_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+ else if (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+ int numGroupCols , double numGroups ,
584+ Cost input_startup_cost , Cost input_total_cost ,
585+ double input_tuples )
586+ {
587+ Cost startup_cost ;
588+ Cost total_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 ;
0 commit comments