@@ -228,18 +228,48 @@ learnOnPlanState(PlanState *p, void *context)
228
228
if (p -> instrument && (p -> righttree != NULL || p -> lefttree == NULL ||
229
229
p -> plan -> path_clauses != NIL ))
230
230
{
231
- double learn_rows ;
231
+ double learn_rows = 0. ;
232
+ double predicted ;
232
233
233
234
InstrEndLoop (p -> instrument );
234
- if (p -> instrument -> nloops > 0 )
235
+ if (p -> instrument -> nloops > 0. )
235
236
{
236
- learn_rows = p -> instrument -> ntuples / p -> instrument -> nloops ;
237
+ /* If we can strongly calculate produced rows, do it. */
238
+ if (p -> worker_instrument )
239
+ {
240
+ double wnloops = 0. ;
241
+ double wntuples = 0. ;
242
+ int i ;
243
+
244
+ for (i = 0 ; i < p -> worker_instrument -> num_workers ; i ++ )
245
+ {
246
+ double t = p -> worker_instrument -> instrument [i ].ntuples ;
247
+ double l = p -> worker_instrument -> instrument [i ].nloops ;
248
+ wntuples += t ;
249
+ wnloops += l ;
250
+ learn_rows += t /l ;
251
+ }
252
+
253
+ Assert (p -> instrument -> nloops >= wnloops );
254
+ Assert (p -> instrument -> ntuples >= wntuples );
255
+ if (p -> instrument -> nloops - wnloops > 0.5 )
256
+ learn_rows += (p -> instrument -> ntuples - wntuples ) /
257
+ (p -> instrument -> nloops - wnloops );
258
+ }
259
+ else
260
+ /* We don't have any workers. */
261
+ learn_rows = p -> instrument -> ntuples / p -> instrument -> nloops ;
237
262
238
- if (p -> plan -> parallel_aware || (p -> plan -> path_parallel_workers > 0 &&
263
+ if (p -> plan -> predicted_cardinality > 0. )
264
+ predicted = p -> plan -> predicted_cardinality ;
265
+ else if (p -> plan -> parallel_aware ||
266
+ (p -> plan -> path_parallel_workers > 0 &&
239
267
(nodeTag (p -> plan ) == T_HashJoin ||
240
268
nodeTag (p -> plan ) == T_MergeJoin ||
241
269
nodeTag (p -> plan ) == T_NestLoop )))
242
- learn_rows *= (p -> plan -> path_parallel_workers + 1 );
270
+ predicted = p -> plan -> plan_rows * get_parallel_divisor (p -> plan -> path_parallel_workers );
271
+ else
272
+ predicted = p -> plan -> plan_rows ;
243
273
244
274
/* It is needed for correct exp(result) calculation. */
245
275
if (learn_rows < 1. )
@@ -260,8 +290,8 @@ learnOnPlanState(PlanState *p, void *context)
260
290
* than a subtree will never be visited.
261
291
*/
262
292
if (!(p -> instrument -> ntuples <= 0. && p -> instrument -> nloops <= 0. ))
263
- learn_sample (ctx -> clauselist , ctx -> selectivities , ctx -> relidslist ,
264
- learn_rows , p -> plan -> plan_rows );
293
+ learn_sample (ctx -> clauselist , ctx -> selectivities ,
294
+ ctx -> relidslist , learn_rows , predicted );
265
295
}
266
296
}
267
297
0 commit comments