/* Maximum number of items to consider in join selectivity calculations */ #define MAX_CONSIDERED_ELEMS 1024
static Selectivity networkjoinsel_inner(Oid operator, int opr_codenum,
VariableStatData *vardata1, VariableStatData *vardata2); static Selectivity networkjoinsel_semi(Oid operator, int opr_codenum,
VariableStatData *vardata1, VariableStatData *vardata2); static Selectivity mcv_population(float4 *mcv_numbers, int mcv_nvalues); static Selectivity inet_hist_value_sel(Datum *values, int nvalues,
Datum constvalue, int opr_codenum); static Selectivity inet_mcv_join_sel(Datum *mcv1_values,
float4 *mcv1_numbers, int mcv1_nvalues, Datum *mcv2_values,
float4 *mcv2_numbers, int mcv2_nvalues, Oid operator); static Selectivity inet_mcv_hist_sel(Datum *mcv_values, float4 *mcv_numbers, int mcv_nvalues, Datum *hist_values, int hist_nvalues, int opr_codenum); static Selectivity inet_hist_inclusion_join_sel(Datum *hist1_values, int hist1_nvalues,
Datum *hist2_values, int hist2_nvalues, int opr_codenum); static Selectivity inet_semi_join_sel(Datum lhs_value, bool mcv_exists, Datum *mcv_values, int mcv_nvalues, bool hist_exists, Datum *hist_values, int hist_nvalues, double hist_weight,
FmgrInfo *proc, int opr_codenum); staticint inet_opr_codenum(Oid operator); staticint inet_inclusion_cmp(inet *left, inet *right, int opr_codenum); staticint inet_masklen_inclusion_cmp(inet *left, inet *right, int opr_codenum); staticint inet_hist_match_divider(inet *boundary, inet *query, int opr_codenum);
/* *Selectivityestimationforthesubnetinclusion/overlapoperators
*/
Datum
networksel(PG_FUNCTION_ARGS)
{
PlannerInfo *root = (PlannerInfo *) PG_GETARG_POINTER(0);
Oid operator = PG_GETARG_OID(1);
List *args = (List *) PG_GETARG_POINTER(2); int varRelid = PG_GETARG_INT32(3); int opr_codenum;
VariableStatData vardata;
Node *other; bool varonleft;
Selectivity selec,
mcv_selec,
non_mcv_selec;
Datum constvalue;
Form_pg_statistic stats;
AttStatsSlot hslot; double sumcommon,
nullfrac;
FmgrInfo proc;
/* *Can'tdoanythingusefulifthesomethingisnotaconstant,either.
*/ if (!IsA(other, Const))
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(DEFAULT_SEL(operator));
}
/* All of the operators handled here are strict. */ if (((Const *) other)->constisnull)
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(0.0);
}
constvalue = ((Const *) other)->constvalue;
/* Otherwise, we need stats in order to produce a non-default estimate. */ if (!HeapTupleIsValid(vardata.statsTuple))
{
ReleaseVariableStats(vardata);
PG_RETURN_FLOAT8(DEFAULT_SEL(operator));
}
/* *Ifwehaveahistogram,useittoestimatetheproportionofthe *non-MCVpopulationthatsatisfiestheclause.Ifwedon't,applythe *defaultselectivitytothatpopulation.
*/ if (get_attstatsslot(&hslot, vardata.statsTuple,
STATISTIC_KIND_HISTOGRAM, InvalidOid,
ATTSTATSSLOT_VALUES))
{ int h_codenum;
/* Commute if needed, so we can consider histogram to be on the left */
h_codenum = varonleft ? opr_codenum : -opr_codenum;
non_mcv_selec = inet_hist_value_sel(hslot.values, hslot.nvalues,
constvalue, h_codenum);
/* guard against zero-divide below */ if (nvalues <= 1) return0.0;
/* if there are too many histogram elements, decimate to limit runtime */
k = (nvalues - 2) / MAX_CONSIDERED_ELEMS + 1;
query = DatumGetInetPP(constvalue);
/* "left" is the left boundary value of the current bucket ... */
left = DatumGetInetPP(values[0]);
left_order = inet_inclusion_cmp(left, query, opr_codenum);
n = 0; for (i = k; i < nvalues; i += k)
{ /* ... and "right" is the right boundary value */
right = DatumGetInetPP(values[i]);
right_order = inet_inclusion_cmp(right, query, opr_codenum);
for (i = 0; i < mcv_nvalues; i++)
{
selec += mcv_numbers[i] *
inet_hist_value_sel(hist_values, hist_nvalues, mcv_values[i],
opr_codenum);
} return selec;
}
/* *Inethistogramvshistogramjoinselectivityestimation * *Here,wetakeallvalueslistedinthesecondhistogram(exceptforthe *firstandlastelements,whichareexcludedonthegroundsofpossibly *notbeingveryrepresentative)andtreatthemasauniformsampleof *thenon-MCVpopulationforthatrelation.Foreachone,weapply *inet_hist_value_selectoseewhatfractionofthefirsthistogram *itmatches. * *Wecouldalternativelydothistheotherwayaroundusingtheoperator's *commutator.XXXwoulditbeworthwhiletodoitbothwaysandtakethe *average?Thatwouldatleastavoidnon-commutativeestimationresults.
*/ static Selectivity
inet_hist_inclusion_join_sel(Datum *hist1_values, int hist1_nvalues,
Datum *hist2_values, int hist2_nvalues, int opr_codenum)
{ double match = 0.0; int i,
k,
n;
if (hist2_nvalues <= 2) return0.0; /* no interior histogram elements */
/* if there are too many histogram elements, decimate to limit runtime */
k = (hist2_nvalues - 3) / MAX_CONSIDERED_ELEMS + 1;
n = 0; for (i = 1; i < hist2_nvalues - 1; i += k)
{
match += inet_hist_value_sel(hist1_values, hist1_nvalues,
hist2_values[i], opr_codenum);
n++;
}
return match / n;
}
/* *Inetsemijoinselectivityestimationforonevalue * *Thefunctioncalculatestheprobabilitythatthereisatleastonerow *intheRHStablethatsatisfiesthe"lhs_valueopcolumn"condition. *Itisusedinsemijoinestimationtocheckasamplefromthelefthand *sidetable. * *TheMCVandhistogramfromtherighthandsidetableshouldbeprovidedas *argumentswiththelhs_valuefromthelefthandsidetableforthejoin. *hist_weightisthetotalnumberofrowsrepresentedbythehistogram. *Forexample,ifthetablehas1000rows,and10%oftherowsareintheMCV *list,andanother10%areNULLs,hist_weightwouldbe800. * *First,thelhs_valuewillbematchedtothemostcommonvalues.Ifit *matchesanyofthem,1.0willbereturned,becausethenthereissurely *amatch. * *Otherwise,thehistogramwillbeusedtoestimatethenumberofrowsin *thesecondtablethatmatchthecondition.Iftheestimateisgreater *than1.0,1.0willbereturned,becauseitmeansthereisagreaterchance *thatthelhs_valuewillmatchmorethanonerowinthetable.Ifitis *between0.0and1.0,itwillbereturnedastheprobability.
*/ static Selectivity
inet_semi_join_sel(Datum lhs_value, bool mcv_exists, Datum *mcv_values, int mcv_nvalues, bool hist_exists, Datum *hist_values, int hist_nvalues, double hist_weight,
FmgrInfo *proc, int opr_codenum)
{ if (mcv_exists)
{ int i;
for (i = 0; i < mcv_nvalues; i++)
{ if (DatumGetBool(FunctionCall2(proc,
lhs_value,
mcv_values[i]))) return1.0;
}
}
if (hist_exists && hist_weight > 0)
{
Selectivity hist_selec;
/* Commute operator, since we're passing lhs_value on the right */
hist_selec = inet_hist_value_sel(hist_values, hist_nvalues,
lhs_value, -opr_codenum);
if (hist_selec > 0) return Min(1.0, hist_weight * hist_selec);
}
return0.0;
}
/* *Assignusefulcodenumbersforthesubnetinclusion/overlapoperators * *Thiswillthrowanerroriftheoperatorisnotoneoftheoneswe *supportinnetworksel()andnetworkjoinsel(). * *Onlyinet_masklen_inclusion_cmp()andinet_hist_match_divider()depend *ontheexactcodesassignedhere;butmanyotherplacesinthisfile *knowthattheycannegateacodetoobtainthecodeforthecommutator *operator.
*/ staticint
inet_opr_codenum(Oid operator)
{ switch (operator)
{ case OID_INET_SUP_OP: return -2; case OID_INET_SUPEQ_OP: return -1; case OID_INET_OVERLAP_OP: return0; case OID_INET_SUBEQ_OP: return1; case OID_INET_SUB_OP: return2; default:
elog(ERROR, "unrecognized operator %u for inet selectivity", operator);
} return0; /* unreached, but keep compiler quiet */
}
¤ Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.0.35Bemerkung:
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.