37
37
#include "partutils.h"
38
38
#include "stream.h"
39
39
40
+ #define DEFAULT_EXCHANGE_STARTUP_COST 100.0
41
+ #define DEFAULT_TRANSFER_TUPLE_COST 0.01
42
+
40
43
41
44
static CustomPathMethods exchange_path_methods ;
42
45
static CustomScanMethods exchange_plan_methods ;
@@ -401,9 +404,13 @@ add_exchange_paths(PlannerInfo *root, RelOptInfo *rel, Index rti, RangeTblEntry
401
404
}
402
405
}
403
406
407
+ #include "optimizer/cost.h"
408
+
404
409
static void
405
- cost_exchange (PlannerInfo * root , RelOptInfo * baserel , Path * path )
410
+ cost_exchange (PlannerInfo * root , RelOptInfo * baserel , ExchangePath * expath )
406
411
{
412
+ Path * subpath ;
413
+
407
414
if (baserel -> pages == 0 && baserel -> tuples == 0 )
408
415
{
409
416
baserel -> pages = 10 ;
@@ -414,11 +421,53 @@ cost_exchange(PlannerInfo *root, RelOptInfo *baserel, Path *path)
414
421
415
422
/* Estimate baserel size as best we can with local statistics. */
416
423
// set_baserel_size_estimates(root, baserel);
424
+ subpath = cstmSubPath1 (expath );
425
+ expath -> cp .path .rows = baserel -> tuples ;
426
+ expath -> cp .path .startup_cost = subpath -> startup_cost ;
427
+ switch (expath -> mode )
428
+ {
429
+ case EXCH_GATHER :
430
+ expath -> cp .path .startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
431
+ expath -> cp .path .rows = subpath -> rows * expath -> altrel .nparts ;
432
+ break ;
433
+ case EXCH_STEALTH :
434
+ expath -> cp .path .rows = subpath -> rows ;
435
+ break ;
436
+ case EXCH_BROADCAST :
437
+ expath -> cp .path .startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
438
+ expath -> cp .path .rows = subpath -> rows * expath -> altrel .nparts ;
439
+ break ;
440
+ case EXCH_SHUFFLE :
441
+ {
442
+ double local_rows ;
443
+ double received_rows ;
444
+ double send_rows ;
445
+ int instances ;
446
+ Path * path = & expath -> cp .path ;
447
+
448
+ path -> startup_cost += DEFAULT_EXCHANGE_STARTUP_COST ;
449
+ path -> total_cost += path -> startup_cost ;
417
450
418
- /* Now I do not want to think about cost estimations. */
419
- path -> rows = baserel -> tuples ;
420
- path -> startup_cost = 0.1 ;
421
- path -> total_cost = 0.1 ;
451
+ /*
452
+ * We count on perfect balance of tuple distribution:
453
+ * If we have N instances, M tuples from subtree, than we send up to
454
+ * local subtree M/N tuples, send to network [M-M/N] tuples and same to
455
+ * receive.
456
+ */
457
+ path -> rows = subpath -> rows ;
458
+ instances = expath -> altrel .nparts > 0 ? expath -> altrel .nparts : 2 ;
459
+ send_rows = path -> rows - (path -> rows /instances );
460
+ received_rows = send_rows ;
461
+ local_rows = path -> rows /instances ;
462
+ path -> total_cost += (send_rows + local_rows ) * DEFAULT_CPU_TUPLE_COST ;
463
+ path -> total_cost += (received_rows ) * DEFAULT_CPU_TUPLE_COST * 4. ;
464
+ }
465
+ break ;
466
+ default :
467
+ elog (FATAL , "Unknown EXCHANGE mode." );
468
+ }
469
+
470
+ expath -> cp .path .total_cost = 0.1 ;
422
471
}
423
472
424
473
/*
@@ -663,8 +712,6 @@ create_exchange_path(PlannerInfo *root, RelOptInfo *rel, Path *children,
663
712
pathnode -> parallel_workers = 0 ; /* permanently */
664
713
pathnode -> pathkeys = NIL ;
665
714
666
- cost_exchange (root , rel , pathnode ); /* Change at next step*/
667
-
668
715
path -> flags = 0 ;
669
716
/* Contains only one path */
670
717
path -> custom_paths = lappend (path -> custom_paths , children );
@@ -675,6 +722,7 @@ create_exchange_path(PlannerInfo *root, RelOptInfo *rel, Path *children,
675
722
memcpy (& epath -> altrel , rel , sizeof (RelOptInfo ));
676
723
epath -> exchange_counter = exchange_counter ++ ;
677
724
epath -> mode = mode ;
725
+ cost_exchange (root , rel , epath ); /* Change at next step*/
678
726
679
727
return epath ;
680
728
}
0 commit comments