summaryrefslogtreecommitdiff
path: root/sql/opt_range.cc
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2016-06-02 19:00:26 +0300
committerSergei Petrunia <psergey@askmonty.org>2016-06-02 19:02:01 +0300
commit7d3d75895d9d29d52c34dd3559cec59731d8d267 (patch)
tree04201821e7854704d725333bd7bf6ff6094a3544 /sql/opt_range.cc
parent66dd9fa397acb2eaf4df17facc8f144b10b1ccdf (diff)
downloadmariadb-git-7d3d75895d9d29d52c34dd3559cec59731d8d267.tar.gz
MDEV-9764: MariaDB does not limit memory used for range optimization
Part #2: make tree_or(tree1, tree2) to reuse tree1 for the result object for simple cases. These include key IN (c1, ... cN). The reuse was happening in old MySQL versions, but we stopped doing it in the "fair choice between range and index_merge" patch.
Diffstat (limited to 'sql/opt_range.cc')
-rw-r--r--sql/opt_range.cc28
1 files changed, 25 insertions, 3 deletions
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index 0c8166c13f8..3d059abd666 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -8566,14 +8566,30 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
imerge[0]= new SEL_IMERGE(tree1->merges.head(), 0, param);
}
bool no_imerge_from_ranges= FALSE;
- if (!(result= new (param->mem_root) SEL_TREE(param->mem_root, param->keys)))
- DBUG_RETURN(result);
/* Build the range part of the tree for the formula (1) */
if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
{
bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
no_imerge_from_ranges= must_be_ored;
+
+ if (no_imerge_from_ranges && no_merges1 && no_merges2)
+ {
+ /*
+ Reuse tree1 as the result in simple cases. This reduces memory usage
+ for e.g. "key IN (c1, ..., cN)" which produces a lot of ranges.
+ */
+ result= tree1;
+ }
+ else
+ {
+ if (!(result= new (param->mem_root) SEL_TREE(param->mem_root,
+ param->keys)))
+ {
+ DBUG_RETURN(result);
+ }
+ }
+
key_map::Iterator it(ored_keys);
int key_no;
while ((key_no= it++) != key_map::Iterator::BITMAP_END)
@@ -8590,7 +8606,13 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
}
result->type= tree1->type;
}
-
+ else
+ {
+ if (!result && !(result= new (param->mem_root) SEL_TREE(param->mem_root,
+ param->keys)))
+ DBUG_RETURN(result);
+ }
+
if (no_imerge_from_ranges && no_merges1 && no_merges2)
{
if (result->keys_map.is_clear_all())