Changeset: 5c48576a3cfd for MonetDB
URL: https://dev.monetdb.org/hg/MonetDB/rev/5c48576a3cfd
Modified Files:
sql/server/rel_exp.c
sql/server/rel_exp.h
sql/server/rel_optimize_sel.c
sql/server/rel_rel.c
sql/server/rel_rel.h
sql/server/rel_rewriter.c
sql/server/rel_rewriter.h
sql/server/rel_statistics.c
Branch: default
Log Message:
improved duplicate relation detection
small improvement of selectivity estimation on selects (nulls) over left outer
joins
diffs (241 lines):
diff --git a/sql/server/rel_exp.c b/sql/server/rel_exp.c
--- a/sql/server/rel_exp.c
+++ b/sql/server/rel_exp.c
@@ -4333,7 +4333,7 @@ free_exp(allocator *sa, sql_exp *e)
}
dbl
-exp_estimate_selectivity(mvc *sql, sql_exp *e)
+exp_estimate_selectivity(mvc *sql, sql_exp *e, sql_rel *rel)
{
dbl sel = 0.1;
(void)sql;
@@ -4349,7 +4349,7 @@ exp_estimate_selectivity(mvc *sql, sql_e
case e_column:
return 0.1;
case e_convert:
- return exp_estimate_selectivity(sql, (sql_exp *) e->l);
+ return exp_estimate_selectivity(sql, (sql_exp *) e->l, rel);
case e_func:
return 0.1;
case e_aggr:
@@ -4362,11 +4362,21 @@ exp_estimate_selectivity(mvc *sql, sql_e
switch (e->flag) {
case cmp_equal:
if (exp_is_atom(r) && !exp_is_atom(l)) {
- prop *p = find_prop(l->p,
PROP_NUNIQUES);
- if (p && p->value.dval > 1)
- sel = 1.0 / p->value.dval;
- else
- sel = 0.1;
+ /* assumes select over left outer */
+ sql_rel *i = rel->l;
+ if (is_select(rel->op) && i &&
is_left(i->op) && exp_is_null(r)) {
+ BUN v = (get_rel_count(i->l) -
get_rel_count(i->r));
+ if (v)
+ sel =
get_rel_count(i->l)/v;
+ else
+ sel = 0.1;
+ } else {
+ prop *p = find_prop(l->p,
PROP_NUNIQUES);
+ if (p && p->value.dval > 1)
+ sel = 1.0 /
p->value.dval;
+ else
+ sel = 0.1;
+ }
} else if (exp_is_atom(l) && !exp_is_atom(r)) {
prop *p = find_prop(r->p,
PROP_NUNIQUES);
if (p && p->value.dval > 1)
@@ -4430,14 +4440,14 @@ exp_estimate_selectivity(mvc *sql, sql_e
list *lst = (list *) e->l;
sel = 1.0;
for (node *n = lst->h; n; n = n->next)
- sel *= exp_estimate_selectivity(sql,
(sql_exp *) n->data);
+ sel *= exp_estimate_selectivity(sql,
(sql_exp *) n->data, rel);
break;
}
case cmp_dis: {
list *lst = (list *) e->l;
sel = 0.0;
for (node *n = lst->h; n; n = n->next)
- sel += exp_estimate_selectivity(sql, (sql_exp
*) n->data);
+ sel += exp_estimate_selectivity(sql, (sql_exp
*) n->data, rel);
if (sel > 1.0)
sel = 1.0;
break;
diff --git a/sql/server/rel_exp.h b/sql/server/rel_exp.h
--- a/sql/server/rel_exp.h
+++ b/sql/server/rel_exp.h
@@ -212,7 +212,7 @@ extern sql_exp *exps_bind_column2(list *
extern sql_exp * list_find_exp(const list *exps, sql_exp *e);
extern sql_exp *predicates_find_nid(const list *exps, int nid);
-extern dbl exp_estimate_selectivity(mvc *sql, sql_exp *e);
+extern dbl exp_estimate_selectivity(mvc *sql, sql_exp *e, sql_rel *rel);
extern unsigned int exps_card( list *l );
extern void exps_fix_card( list *exps, unsigned int card);
extern void exps_setcard( list *exps, unsigned int card);
diff --git a/sql/server/rel_optimize_sel.c b/sql/server/rel_optimize_sel.c
--- a/sql/server/rel_optimize_sel.c
+++ b/sql/server/rel_optimize_sel.c
@@ -2851,7 +2851,7 @@ exp_selectivity(visitor *v, sql_exp *e,
}
}
} else {
- dbl s = exp_estimate_selectivity(v->sql, e);
+ dbl s = exp_estimate_selectivity(v->sql, e, l);
/* store selectivity on predicate for later use */
if (!p)
p = prop_create(v->sql->sa, PROP_SELECTIVITY, e->p);
diff --git a/sql/server/rel_rel.c b/sql/server/rel_rel.c
--- a/sql/server/rel_rel.c
+++ b/sql/server/rel_rel.c
@@ -2045,6 +2045,43 @@ rel_zero_or_one(mvc *sql, sql_rel *rel,
return rel;
}
+BUN
+get_rel_count(sql_rel *rel)
+{
+ if (rel && is_physical(rel->op) && rel->l)
+ return get_rel_count(rel->l);
+ prop *found = find_prop(rel->p, PROP_COUNT);
+ if (!found && rel && is_simple_project(rel->op) && rel->l)
+ return get_rel_count(rel->l);
+ if (!found && rel && is_munion(rel->op) && rel->l) {
+ BUN res = 0;
+ for(node *n = ((list*)rel->l)->h; n; n = n->next) {
+ BUN ires = get_rel_count(n->data);
+ if (ires == BUN_NONE)
+ return BUN_NONE;
+ res += ires;
+ }
+ return res;
+ }
+ return found ? found->value.lval : BUN_NONE;
+}
+
+void
+set_count_prop(allocator *sa, sql_rel *rel, BUN val)
+{
+ if (val != BUN_NONE) {
+ prop *found = find_prop(rel->p, PROP_COUNT);
+
+ if (found) {
+ found->value.lval = val;
+ } else {
+ prop *p = rel->p = prop_create(sa, PROP_COUNT, rel->p);
+ p->value.lval = val;
+ }
+ }
+}
+
+
static sql_rel *
refs_find_rel(list *refs, sql_rel *rel)
{
diff --git a/sql/server/rel_rel.h b/sql/server/rel_rel.h
--- a/sql/server/rel_rel.h
+++ b/sql/server/rel_rel.h
@@ -138,6 +138,8 @@ extern sql_rel *rel_parent(sql_rel *rel)
extern sql_exp *lastexp(sql_rel *rel);
extern sql_rel *rel_return_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek);
extern sql_rel *rel_zero_or_one(mvc *sql, sql_rel *rel, exp_kind ek);
+extern BUN get_rel_count(sql_rel *rel);
+extern void set_count_prop(allocator *sa, sql_rel *rel, BUN val);
extern list *rel_dependencies(mvc *sql, sql_rel *r);
diff --git a/sql/server/rel_rewriter.c b/sql/server/rel_rewriter.c
--- a/sql/server/rel_rewriter.c
+++ b/sql/server/rel_rewriter.c
@@ -546,39 +546,3 @@ exps_unique(mvc *sql, sql_rel *rel, list
}
return 0;
}
-
-BUN
-get_rel_count(sql_rel *rel)
-{
- if (rel && is_physical(rel->op) && rel->l)
- return get_rel_count(rel->l);
- prop *found = find_prop(rel->p, PROP_COUNT);
- if (!found && rel && is_simple_project(rel->op) && rel->l)
- return get_rel_count(rel->l);
- if (!found && rel && is_munion(rel->op) && rel->l) {
- BUN res = 0;
- for(node *n = ((list*)rel->l)->h; n; n = n->next) {
- BUN ires = get_rel_count(n->data);
- if (ires == BUN_NONE)
- return BUN_NONE;
- res += ires;
- }
- return res;
- }
- return found ? found->value.lval : BUN_NONE;
-}
-
-void
-set_count_prop(allocator *sa, sql_rel *rel, BUN val)
-{
- if (val != BUN_NONE) {
- prop *found = find_prop(rel->p, PROP_COUNT);
-
- if (found) {
- found->value.lval = val;
- } else {
- prop *p = rel->p = prop_create(sa, PROP_COUNT, rel->p);
- p->value.lval = val;
- }
- }
-}
diff --git a/sql/server/rel_rewriter.h b/sql/server/rel_rewriter.h
--- a/sql/server/rel_rewriter.h
+++ b/sql/server/rel_rewriter.h
@@ -51,7 +51,4 @@ extern int exps_unique(mvc *sql, sql_rel
extern sql_column *exp_find_column(sql_rel *rel, sql_exp *exp, int pnr);
-extern BUN get_rel_count(sql_rel *rel);
-extern void set_count_prop(allocator *sa, sql_rel *rel, BUN val);
-
#endif /*_REL_REWRITER_H_*/
diff --git a/sql/server/rel_statistics.c b/sql/server/rel_statistics.c
--- a/sql/server/rel_statistics.c
+++ b/sql/server/rel_statistics.c
@@ -1075,7 +1075,7 @@ rel_get_statistics_(visitor *v, sql_rel
sql_exp *e = n->data;
prop *sp = NULL;
if ((sp = find_prop(e->p,
PROP_SELECTIVITY)) == NULL) {
- dbl s =
exp_estimate_selectivity(v->sql, e);
+ dbl s =
exp_estimate_selectivity(v->sql, e, rel);
/* store selectivity on
predicate for later use */
sp =
prop_create(v->sql->sa, PROP_SELECTIVITY, e->p);
sp->value.dval = s;
@@ -1110,7 +1110,7 @@ rel_get_statistics_(visitor *v, sql_rel
dbl sel = 1.0;
for (node *n = rel->exps->h ; n ; n =
n->next) {
sql_exp *e = n->data;
- dbl s =
exp_estimate_selectivity(v->sql, e);
+ dbl s =
exp_estimate_selectivity(v->sql, e, rel);
/* store selectivity on
predicate for later use */
prop *sp =
prop_create(v->sql->sa, PROP_SELECTIVITY, (prop *) e->p);
sp->value.dval = s;
@@ -1697,7 +1697,7 @@ rel_estimate(visitor *v, sql_rel *rel)
sql_exp *e = n->data;
prop *sp = NULL;
if ((sp = find_prop(e->p,
PROP_SELECTIVITY)) == NULL) {
- dbl s =
exp_estimate_selectivity(v->sql, e);
+ dbl s =
exp_estimate_selectivity(v->sql, e, rel);
/* store selectivity on
predicate for later use */
sp = prop_create(v->sql->sa,
PROP_SELECTIVITY, e->p);
sp->value.dval = s;
@@ -1730,7 +1730,7 @@ rel_estimate(visitor *v, sql_rel *rel)
dbl sel = 1.0;
for (node *n = rel->exps->h ; n ; n = n->next) {
sql_exp *e = n->data;
- dbl s =
exp_estimate_selectivity(v->sql, e);
+ dbl s =
exp_estimate_selectivity(v->sql, e, rel);
/* store selectivity on predicate for
later use */
prop *sp = prop_create(v->sql->sa,
PROP_SELECTIVITY, (prop *) e->p);
sp->value.dval = s;
_______________________________________________
checkin-list mailing list -- [email protected]
To unsubscribe send an email to [email protected]