Changeset: cd849937fc9d for MonetDB
URL: http://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=cd849937fc9d
Modified Files:
sql/backends/monet5/UDF/udf.mal
sql/backends/monet5/sql_result.mx
sql/server/rel_bin.c
sql/server/rel_optimizer.c
sql/server/rel_prop.c
sql/server/rel_prop.h
sql/server/rel_select.c
sql/server/sql_rel2bin.c
sql/server/sql_statement.c
sql/server/sql_statement.h
Branch: Dec2011
Log Message:
fixed slowdown of inserts. Don't recompute hash columns for each
insert (multi-column keys).
diffs (truncated from 734 to 300 lines):
diff --git a/sql/backends/monet5/UDF/udf.mal b/sql/backends/monet5/UDF/udf.mal
--- a/sql/backends/monet5/UDF/udf.mal
+++ b/sql/backends/monet5/UDF/udf.mal
@@ -26,4 +26,4 @@ module batudf;
command reverse(b:bat[:oid,:str]):bat[:oid,:str]
address UDFBATreverse
-comment "Reverse a BAT of strings");
+comment "Reverse a BAT of strings";
diff --git a/sql/backends/monet5/sql_result.mx
b/sql/backends/monet5/sql_result.mx
--- a/sql/backends/monet5/sql_result.mx
+++ b/sql/backends/monet5/sql_result.mx
@@ -607,17 +607,24 @@ mvc_import_table(Client cntxt, mvc *m, b
if (locked) {
BAT *b = store_funcs.bind_col(m->session->tr,
col, RDONLY);
- BATmmap(b, STORE_MMAP, STORE_MMAP,
STORE_MMAP, STORE_MMAP, 1);
+
+ if (sz < 0 || sz > (lng)REMAP_PAGE_MAXSIZE)
+ BATmmap(b, STORE_MMAP,
STORE_MMAP, STORE_MMAP, STORE_MMAP, 1);
+ if (sz > (lng)BATTINY)
+ b = BATextend(b, sz);
+
HASHremove(b);
HASHremove(BATmirror(b));
fmt[i].c[0] = b;
cnt = BATcount(b);
- if ( sz > 0 && BATcapacity(b) < (BUN) sz )
+ if ( sz > 0 && BATcapacity(b) < (BUN) sz ) {
if ( (fmt[i].c[0] =
BATextend(fmt[i].c[0], (BUN) sz)) == NULL){
- for ( i--; i>=0; i--)
- BBPunfix(
fmt[i].c[0]->batCacheid);
- sql_error(m, 500,
"failed to allocate result table sizes ");
+ for ( i--; i>=0; i--)
+ BBPunfix(
fmt[i].c[0]->batCacheid);
+ sql_error(m, 500, "failed to
allocate result table sizes ");
+ return NULL;
+ }
}
fmt[i].ci[0] = bat_iterator(fmt[i].c[0]);
}
diff --git a/sql/server/rel_bin.c b/sql/server/rel_bin.c
--- a/sql/server/rel_bin.c
+++ b/sql/server/rel_bin.c
@@ -709,7 +709,7 @@ rel2bin_sql_table(mvc *sql, sql_table *t
char *rnme = sa_strdup(sql->sa, tname);
for (n = t->idxs.set->h; n; n = n->next) {
sql_idx *i = n->data;
- stmt *sc = stmt_idxbat(sql->sa, i, RDONLY);
+ stmt *sc = stmt_idxbat(sql->sa, i, ts, RDONLY);
/* index names are prefixed, to make them independent */
sc = stmt_alias(sql->sa, sc, rnme,
sa_strconcat(sql->sa, "%", i->base.name));
@@ -749,7 +749,7 @@ rel2bin_basetable( mvc *sql, sql_rel *re
if (t->idxs.set) {
for (n = t->idxs.set->h; n; n = n->next) {
sql_idx *i = n->data;
- stmt *sc = stmt_idxbat(sql->sa, i, RDONLY);
+ stmt *sc = stmt_idxbat(sql->sa, i, ts, RDONLY);
char *rnme = sa_strdup(sql->sa, t->base.name);
/* index names are prefixed, to make them independent */
@@ -842,6 +842,77 @@ rel2bin_table( mvc *sql, sql_rel *rel, l
}
static stmt *
+rel2bin_hash_lookup( mvc *sql, sql_rel *rel, stmt *left, stmt *right, sql_idx
*i, node *en )
+{
+ node *n;
+ sql_subtype *it = sql_bind_localtype("int");
+ sql_subtype *wrd = sql_bind_localtype("wrd");
+ stmt *h = NULL;
+ stmt *bits = stmt_atom_int(sql->sa, 1 +
((sizeof(wrd)*8)-1)/(list_length(i->columns)+1));
+ sql_exp *e = en->data;
+ sql_exp *l = e->l;
+ stmt *idx = bin_find_column(sql->sa, left, l->l, sa_strconcat(sql->sa,
"%", i->base.name));
+ int swap_exp = 0, swap_rel = 0;
+
+ if (!idx) {
+ swap_exp = 1;
+ l = e->r;
+ idx = bin_find_column(sql->sa, left, l->l,
sa_strconcat(sql->sa, "%", i->base.name));
+ }
+ if (!idx) {
+ swap_exp = 0;
+ swap_rel = 1;
+ l = e->l;
+ idx = bin_find_column(sql->sa, right, l->l,
sa_strconcat(sql->sa, "%", i->base.name));
+ }
+ if (!idx) {
+ swap_exp = 1;
+ swap_rel = 1;
+ l = e->r;
+ idx = bin_find_column(sql->sa, right, l->l,
sa_strconcat(sql->sa, "%", i->base.name));
+ }
+ if (!idx)
+ return NULL;
+ /* should be in key order! */
+ for( en = rel->exps->h, n = i->columns->h; en && n; en = en->next, n =
n->next ) {
+ sql_exp *e = en->data;
+ stmt *s = NULL;
+
+ if (e->type == e_cmp && e->flag == cmp_equal) {
+ sql_exp *ee = (swap_exp)?e->l:e->r;
+ if (swap_rel)
+ s = exp_bin(sql, ee, left, NULL, NULL, NULL);
+ else
+ s = exp_bin(sql, ee, right, NULL, NULL, NULL);
+ }
+
+ if (!s)
+ return NULL;
+ if (h) {
+ sql_subfunc *xor = sql_bind_func_result3(sql->sa,
sql->session->schema, "rotate_xor_hash", wrd, it, tail_type(s), wrd);
+
+ h = stmt_Nop(sql->sa, stmt_list(sql->sa, list_append(
list_append(
+ list_append(list_new(sql->sa), h), bits), s)),
xor);
+ } else {
+ sql_subfunc *hf = sql_bind_func_result(sql->sa,
sql->session->schema, "hash", tail_type(s), NULL, wrd);
+
+ h = stmt_unop(sql->sa, s, hf);
+ }
+ }
+ if (h->nrcols) {
+ if (!swap_rel) {
+ h = stmt_reverse(sql->sa, h);
+ return stmt_join(sql->sa, idx, h, cmp_equal);
+ } else {
+ idx = stmt_reverse(sql->sa, idx);
+ return stmt_join(sql->sa, h, idx, cmp_equal);
+ }
+ } else
+ return stmt_uselect(sql->sa, idx, h, cmp_equal);
+}
+
+
+static stmt *
rel2bin_join( mvc *sql, sql_rel *rel, list *refs)
{
list *l;
@@ -863,6 +934,7 @@ rel2bin_join( mvc *sql, sql_rel *rel, li
* second selects/filters
*/
if (rel->exps) {
+ int use_hash = 0;
int idx = 0;
list *jexps = list_new(sql->sa);
list *jns = list_new(sql->sa);
@@ -887,12 +959,25 @@ rel2bin_join( mvc *sql, sql_rel *rel, li
int join_idx = sql->opt_stats[0];
sql_exp *e = en->data;
stmt *s = NULL;
+ prop *p;
/* only handle simple joins here */
- if (list_length(jns) && (idx || !e->type == e_cmp ||
e->flag != cmp_equal))
+ if (list_length(jns) && (idx || e->type != e_cmp ||
e->flag != cmp_equal))
break;
- s = exp_bin(sql, en->data, left, right, NULL, NULL);
+ /* handle possible index lookups */
+ /* expressions are in index order ! */
+ if (!join &&
+ (p=find_prop(e->p, PROP_HASHCOL)) != NULL) {
+ sql_idx *i = p->value;
+
+ join = s = rel2bin_hash_lookup(sql, rel, left,
right, i, en);
+ assert(s);
+ list_append(jns, s);
+ use_hash = 1;
+ }
+
+ s = exp_bin(sql, e, left, right, NULL, NULL);
if (!s) {
assert(0);
return NULL;
@@ -926,6 +1011,8 @@ rel2bin_join( mvc *sql, sql_rel *rel, li
}
if (list_length(jns) > 1) {
join = stmt_releqjoin(sql->sa, jns);
+ if (use_hash)
+ join->flag = NO_HASH;
} else if (!join) {
join = jns->h->data;
}
@@ -1730,43 +1817,6 @@ rel2bin_predicate(mvc *sql)
}
static stmt *
-rel2bin_hash_lookup( mvc *sql, sql_rel *rel, stmt *sub, sql_idx *i, node *en )
-{
- node *n;
- sql_subtype *it = sql_bind_localtype("int");
- sql_subtype *wrd = sql_bind_localtype("wrd");
- stmt *h = NULL;
- stmt *bits = stmt_atom_int(sql->sa, 1 +
((sizeof(wrd)*8)-1)/(list_length(i->columns)+1));
- sql_exp *e = en->data;
- sql_exp *l = e->l;
- stmt *idx = bin_find_column(sql->sa, sub, l->l, sa_strconcat(sql->sa,
"%", i->base.name));
-
- /* should be in key order! */
- for( en = rel->exps->h, n = i->columns->h; en && n; en = en->next, n =
n->next ) {
- sql_exp *e = en->data;
- stmt *s = NULL;
-
- if (e->type == e_cmp && e->flag == cmp_equal)
- s = exp_bin(sql, e->r, NULL, NULL, NULL, NULL);
-
- if (!s)
- return NULL;
- if (h) {
- sql_subfunc *xor = sql_bind_func_result3(sql->sa,
sql->session->schema, "rotate_xor_hash", wrd, it, tail_type(s), wrd);
-
- h = stmt_Nop(sql->sa, stmt_list(sql->sa, list_append(
list_append(
- list_append(list_new(sql->sa), h), bits), s)),
xor);
- } else {
- sql_subfunc *hf = sql_bind_func_result(sql->sa,
sql->session->schema, "hash", tail_type(s), NULL, wrd);
-
- h = stmt_unop(sql->sa, s, hf);
- }
- }
- return stmt_uselect(sql->sa, idx, h, cmp_equal);
-}
-
-
-static stmt *
rel2bin_select( mvc *sql, sql_rel *rel, list *refs)
{
list *l;
@@ -1798,10 +1848,10 @@ rel2bin_select( mvc *sql, sql_rel *rel,
sql_exp *e = en->data;
prop *p;
- if ((p=find_prop(e->p, PROP_HASHIDX)) != NULL) {
+ if ((p=find_prop(e->p, PROP_HASHCOL)) != NULL) {
sql_idx *i = p->value;
- s = rel2bin_hash_lookup(sql, rel, sub, i, en);
+ s = rel2bin_hash_lookup(sql, rel, sub, NULL, i, en);
}
}
sel = stmt_relselect_init(sql->sa);
@@ -2112,7 +2162,7 @@ insert_check_ukey(mvc *sql, list *insert
if (s->key && s->nrcols == 0) {
s = stmt_relselect_init(sql->sa);
if (k->idx && hash_index(k->idx->type))
- stmt_relselect_fill(s, stmt_uselect(sql->sa,
stmt_idxbat(sql->sa, k->idx, RDONLY), idx_inserts, cmp_equal));
+ stmt_relselect_fill(s, stmt_uselect(sql->sa,
stmt_idxbat(sql->sa, k->idx, ts, RDONLY), idx_inserts, cmp_equal));
for (m = k->columns->h; m; m = m->next) {
sql_kc *c = m->data;
@@ -2126,8 +2176,9 @@ insert_check_ukey(mvc *sql, list *insert
}
} else {
s = stmt_releqjoin_init(sql->sa);
- if (k->idx && hash_index(k->idx->type))
- stmt_releqjoin_fill(s, stmt_idxbat(sql->sa,
k->idx, RDONLY), idx_inserts);
+ s->flag = NO_HASH;
+ if (k->idx && hash_index(k->idx->type))
+ stmt_releqjoin_fill(s, stmt_idxbat(sql->sa,
k->idx, ts, RDONLY), idx_inserts);
for (m = k->columns->h; m; m = m->next) {
sql_kc *c = m->data;
@@ -2513,8 +2564,9 @@ update_check_ukey(mvc *sql, stmt **updat
/* TODO split null removal and join/group (to make mkey save) */
if (!isNew(k)) {
s = stmt_releqjoin_init(sql->sa);
+ s->flag = NO_HASH;
if (k->idx && hash_index(k->idx->type))
- stmt_releqjoin_fill(s, stmt_diff(sql->sa,
stmt_idxbat(sql->sa, k->idx, RDONLY), idx_updates), idx_updates);
+ stmt_releqjoin_fill(s, stmt_diff(sql->sa,
stmt_idxbat(sql->sa, k->idx, ts, RDONLY), idx_updates), idx_updates);
for (m = k->columns->h; m; m = m->next) {
sql_kc *c = m->data;
stmt *upd, *l;
@@ -2701,8 +2753,9 @@ join_updated_pkey(mvc *sql, sql_key * k,
fts = stmt_basetable(sql->sa, k->idx->t, k->idx->t->base.name);
s = stmt_releqjoin_init(sql->sa);
-
- rows = stmt_idxbat(sql->sa, k->idx, RDONLY);
+ s->flag = NO_HASH;
+
+ rows = stmt_idxbat(sql->sa, k->idx, fts, RDONLY);
rows = stmt_semijoin(sql->sa, stmt_reverse(sql->sa, rows),
updates[updcol]->op1);
rows = stmt_reverse(sql->sa, rows);
@@ -2799,7 +2852,7 @@ sql_update_cascade_Fkeys(mvc *sql, sql_k
stmt *rows;
sql_table *t = mvc_bind_table(sql, k->t->s, k->t->base.name);
- rows = stmt_idxbat(sql->sa, k->idx, RDONLY);
+ rows = stmt_idxbat(sql->sa, k->idx, NULL, RDONLY);
rows = stmt_semijoin(sql->sa, stmt_reverse(sql->sa, rows),
updates[updcol]->op1);
rows = stmt_reverse(sql->sa, rows);
@@ -3388,7 +3441,7 @@ sql_delete_ukey(mvc *sql, stmt *deletes,
sql_key *fk = n->data;
stmt *s;
_______________________________________________
Checkin-list mailing list
[email protected]
http://mail.monetdb.org/mailman/listinfo/checkin-list