@@ -338,6 +338,17 @@ func (m *Memo) statsForRel(ctx *sql.Context, rel RelExpr) sql.Statistic {
338338 left := jp .Left .RelProps .GetStats ()
339339 right := jp .Right .RelProps .GetStats ()
340340
341+ distinct := math .Max (float64 (left .DistinctCount ()), float64 (right .DistinctCount ()))
342+ if distinct == 0 {
343+ m := math .Max (float64 (left .RowCount ()), float64 (right .RowCount ()))
344+ distinct = m * .80
345+ }
346+
347+ // Assume that the smaller set is surjective onto the larger set, and at least one of the sets is uniformly distributed.
348+ // If so, then the odds that a random element of each set matches can be computed as:
349+ selectivity := 1.0 / float64 (distinct )
350+ card := uint64 (float64 (left .RowCount ()* right .RowCount ()) * selectivity )
351+
341352 var injective bool
342353 var smallestLeft sql.Statistic
343354 var mergeStats sql.Statistic
@@ -346,9 +357,10 @@ func (m *Memo) statsForRel(ctx *sql.Context, rel RelExpr) sql.Statistic {
346357 for n != nil && ! done {
347358 switch n := n .(type ) {
348359 case * LookupJoin :
349- if n .Injective {
360+ leftRows := n .Left .RelProps .GetStats ().RowCount ()
361+ if n .Injective && leftRows < card {
350362 injective = true
351- if smallestLeft == nil || n . Left . RelProps . GetStats (). RowCount () < smallestLeft .RowCount () {
363+ if leftRows < smallestLeft .RowCount () {
352364 smallestLeft = n .Left .RelProps .GetStats ()
353365 }
354366 }
@@ -397,18 +409,7 @@ func (m *Memo) statsForRel(ctx *sql.Context, rel RelExpr) sql.Statistic {
397409 return mergeStats
398410 }
399411
400- distinct := math .Max (float64 (left .DistinctCount ()), float64 (right .DistinctCount ()))
401- if distinct == 0 {
402- m := math .Max (float64 (left .RowCount ()), float64 (right .RowCount ()))
403- distinct = m * .80
404- }
405-
406- // Assume that the smaller set is surjective onto the larger set, and at least one of the sets is uniformly distributed.
407- // If so, then the odds that a random element of each set matches can be computed as:
408- selectivity := 1.0 / float64 (distinct )
409- card := float64 (left .RowCount ()* right .RowCount ()) * selectivity
410- return & stats.Statistic {RowCnt : uint64 (card )}
411-
412+ return & stats.Statistic {RowCnt : card }
412413 case * Max1Row :
413414 stat = & stats.Statistic {RowCnt : 1 }
414415
0 commit comments