MCPcopy Create free account
hub / github.com/apache/cloudberry / cdbpath_cost_motion

Function cdbpath_cost_motion

src/backend/cdb/cdbpath.c:83–171  ·  view source on GitHub ↗

* cdbpath_cost_motion * Fills in the cost estimate fields in a MotionPath node. */

Source from the content-addressed store, hash-verified

81 * Fills in the cost estimate fields in a MotionPath node.
82 */
83void
84cdbpath_cost_motion(PlannerInfo *root, CdbMotionPath *motionpath)
85{
86 Path *subpath = motionpath->subpath;
87 Cost cost_per_row;
88 Cost motioncost;
89 double recvrows;
90 double sendrows;
91 double send_segments = 1;
92 double recv_segments = 1;
93 double total_rows;
94
95 CdbPathLocus sublocus = subpath->locus;
96 CdbPathLocus motionlocus = motionpath->path.locus;
97
98 int mot_parallel = motionlocus.parallel_workers;
99 int sub_parallel = sublocus.parallel_workers;
100
101 if (CdbPathLocus_IsPartitioned(motionlocus))
102 {
103 recv_segments = CdbPathLocus_NumSegments(motionlocus);
104 if (mot_parallel > 0)
105 recv_segments *= mot_parallel;
106 }
107 else if (mot_parallel > 0 && CdbPathLocus_IsReplicatedWorkers(motionlocus))
108 recv_segments *= mot_parallel;
109
110 if (CdbPathLocus_IsPartitioned(sublocus))
111 {
112 send_segments = CdbPathLocus_NumSegments(sublocus);
113 if (sub_parallel > 0)
114 send_segments *= sub_parallel;
115 }
116 else if (sub_parallel > 0 && CdbPathLocus_IsReplicatedWorkers(sublocus))
117 send_segments *= sub_parallel;
118
119 /*
120 * Estimate the total number of rows being sent.
121 * The base estimate is computed by multiplying the subpath's rows with
122 * the number of sending segments. But in some cases, that leads to too
123 * large estimates, if the subpath's estimate was "clamped" to 1 row. The
124 * typical example is a single-row select like "SELECT * FROM table WHERE
125 * key = 123. The Scan on the table returns only one row, on one segment,
126 * and the estimate on the Scan node is 1 row. If you have e.g. 3
127 * segments, and we just multiplied the subpath's row estimate by 3, we
128 * would estimate that the Gather returns 3 rows, even though there is
129 * only one matching row in the table. Using the 'rows' estimate on the
130 * RelOptInfo is more accurate in such cases. To correct that, if the
131 * subpath's estimate is 1 row, but the underlying relation's estimate is
132 * smaller, use the underlying relation's estimate.
133 *
134 * We don't always use the relation's estimate, because there might be
135 * nodes like ProjectSet or Limit in the subpath, in which case the
136 * subpath's estimate is more accurate. Also, the relation might not have
137 * a valid 'rows' estimate; upper rels, for example, do not. So check for
138 * that too.
139 */
140 total_rows = subpath->rows * send_segments;

Calls 1

clamp_row_estFunction · 0.85

Tested by

no test coverage detected