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]

Reply via email to