diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c index 6a4f7b1..bc88423 100644 --- a/src/backend/utils/adt/selfuncs.c +++ b/src/backend/utils/adt/selfuncs.c @@ -2279,6 +2279,14 @@ eqjoinsel_inner(Oid operator, nd1 = get_variable_numdistinct(vardata1, &isdefault1); nd2 = get_variable_numdistinct(vardata2, &isdefault2); + float ndfactor1=1; + float ndfactor2=1; + if (vardata1->rel->rows) + ndfactor1=vardata1->rel->tuples / vardata1->rel->rows; + if (vardata2->rel->rows) + ndfactor2=vardata2->rel->tuples / vardata2->rel->rows; + // ndfactor1=ndfactor2=1; + elog(DEBUG4, "ndfactor %lf %lf", ndfactor1,ndfactor2); opfuncoid = get_opcode(operator); @@ -2375,7 +2383,19 @@ eqjoinsel_inner(Oid operator, } } } + + // you might think we should multiple by ndfactor1*ndfactor2, + // but that gives serious overestimates... + // matchprodfreq*= ndfactor1>ndfactor2?ndfactor1:ndfactor2; + // matchprodfreq*=ndfactor1; + // matchprodfreq*=ndfactor2; + // matchprodfreq*= ndfactor1 nvalues2) + if (nd2 > nvalues2) { totalsel1 += unmatchfreq1 * otherfreq2 / (nd2 - nvalues2); - if (nd2 > nmatches) + elog(DEBUG4, "totalsel1-1 %lf", totalsel1); + } + if (nd2 > nmatches) { totalsel1 += otherfreq1 * (otherfreq2 + unmatchfreq2) / (nd2 - nmatches); + elog(DEBUG4, "totalsel1-2 %lf", totalsel1); + } /* Same estimate from the point of view of relation 2. */ totalsel2 = matchprodfreq; - if (nd1 > nvalues1) + if (nd1 > nvalues1) { totalsel2 += unmatchfreq2 * otherfreq1 / (nd1 - nvalues1); - if (nd1 > nmatches) + elog(DEBUG4, "totalsel2-1 %lf", totalsel2); + } + if (nd1 > nmatches) { totalsel2 += otherfreq2 * (otherfreq1 + unmatchfreq1) / (nd1 - nmatches); + elog(DEBUG4, "totalsel2-2 %lf", totalsel2); + } /* * Use the smaller of the two estimates. This can be justified in @@ -2438,6 +2477,7 @@ eqjoinsel_inner(Oid operator, * the relation with smaller nd. */ selec = (totalsel1 < totalsel2) ? totalsel1 : totalsel2; + elog(DEBUG4, "select(1) %lf", selec); } else { @@ -2469,6 +2509,7 @@ eqjoinsel_inner(Oid operator, selec /= nd1; else selec /= nd2; + elog(DEBUG4, "select(2) %lf", selec); } if (have_mcvs1)