Fix an old error in clause_selectivity: the default selectivity estimate
for unhandled clause types ought to be 0.5, not 1.0. I fear I introduced this silliness due to misreading the intent of the very-poorly-structured code that was there when we inherited the file from Berkeley. The lack of sanity in this behavior was exposed by an example from Sim Zacks. (Arguably this is a bug fix and should be back-patched, but I'm a bit hesitant to introduce a possible planner behavior change in the back branches; it might detune queries that worked acceptably in the past.) While at it, make estimation for DistinctExpr do something marginally realistic, rather than just defaulting.
This commit is contained in:
parent
f3e3f2e158
commit
df62977d00
|
@ -8,7 +8,7 @@
|
||||||
*
|
*
|
||||||
*
|
*
|
||||||
* IDENTIFICATION
|
* IDENTIFICATION
|
||||||
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.89 2008/01/01 19:45:50 momjian Exp $
|
* $PostgreSQL: pgsql/src/backend/optimizer/path/clausesel.c,v 1.90 2008/01/11 17:00:45 tgl Exp $
|
||||||
*
|
*
|
||||||
*-------------------------------------------------------------------------
|
*-------------------------------------------------------------------------
|
||||||
*/
|
*/
|
||||||
|
@ -428,7 +428,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
int varRelid,
|
int varRelid,
|
||||||
JoinType jointype)
|
JoinType jointype)
|
||||||
{
|
{
|
||||||
Selectivity s1 = 1.0; /* default for any unhandled clause type */
|
Selectivity s1 = 0.5; /* default for any unhandled clause type */
|
||||||
RestrictInfo *rinfo = NULL;
|
RestrictInfo *rinfo = NULL;
|
||||||
bool cacheable = false;
|
bool cacheable = false;
|
||||||
|
|
||||||
|
@ -450,7 +450,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
if (rinfo->pseudoconstant)
|
if (rinfo->pseudoconstant)
|
||||||
{
|
{
|
||||||
if (!IsA(rinfo->clause, Const))
|
if (!IsA(rinfo->clause, Const))
|
||||||
return s1;
|
return (Selectivity) 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -517,9 +517,8 @@ clause_selectivity(PlannerInfo *root,
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* XXX not smart about subquery references... any way to do
|
* XXX not smart about subquery references... any way to do
|
||||||
* better?
|
* better than default?
|
||||||
*/
|
*/
|
||||||
s1 = 0.5;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -560,8 +559,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* XXX any way to do better? */
|
/* XXX any way to do better than default? */
|
||||||
s1 = (Selectivity) 0.5;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (not_clause(clause))
|
else if (not_clause(clause))
|
||||||
|
@ -601,7 +599,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
s1 = s1 + s2 - s1 * s2;
|
s1 = s1 + s2 - s1 * s2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (is_opclause(clause))
|
else if (is_opclause(clause) || IsA(clause, DistinctExpr))
|
||||||
{
|
{
|
||||||
Oid opno = ((OpExpr *) clause)->opno;
|
Oid opno = ((OpExpr *) clause)->opno;
|
||||||
bool is_join_clause;
|
bool is_join_clause;
|
||||||
|
@ -642,6 +640,15 @@ clause_selectivity(PlannerInfo *root,
|
||||||
((OpExpr *) clause)->args,
|
((OpExpr *) clause)->args,
|
||||||
varRelid);
|
varRelid);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* DistinctExpr has the same representation as OpExpr, but the
|
||||||
|
* contained operator is "=" not "<>", so we must negate the result.
|
||||||
|
* This estimation method doesn't give the right behavior for nulls,
|
||||||
|
* but it's better than doing nothing.
|
||||||
|
*/
|
||||||
|
if (IsA(clause, DistinctExpr))
|
||||||
|
s1 = 1.0 - s1;
|
||||||
}
|
}
|
||||||
else if (is_funcclause(clause))
|
else if (is_funcclause(clause))
|
||||||
{
|
{
|
||||||
|
@ -652,6 +659,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
*/
|
*/
|
||||||
s1 = (Selectivity) 0.3333333;
|
s1 = (Selectivity) 0.3333333;
|
||||||
}
|
}
|
||||||
|
#ifdef NOT_USED
|
||||||
else if (is_subplan(clause))
|
else if (is_subplan(clause))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
|
@ -659,11 +667,7 @@ clause_selectivity(PlannerInfo *root,
|
||||||
*/
|
*/
|
||||||
s1 = (Selectivity) 0.5;
|
s1 = (Selectivity) 0.5;
|
||||||
}
|
}
|
||||||
else if (IsA(clause, DistinctExpr))
|
#endif
|
||||||
{
|
|
||||||
/* can we do better? */
|
|
||||||
s1 = (Selectivity) 0.5;
|
|
||||||
}
|
|
||||||
else if (IsA(clause, ScalarArrayOpExpr))
|
else if (IsA(clause, ScalarArrayOpExpr))
|
||||||
{
|
{
|
||||||
/* First, decide if it's a join clause, same as for OpExpr */
|
/* First, decide if it's a join clause, same as for OpExpr */
|
||||||
|
|
Loading…
Reference in New Issue