summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergei Petrunia <psergey@askmonty.org>2020-11-09 18:47:55 +0300
committerSergei Petrunia <psergey@askmonty.org>2020-11-09 19:29:21 +0300
commitf81eef62e7742806e5e74b5f37f35b7cd2f82291 (patch)
tree23f0e571625f01d1d42ded5221727ac09e5b184a
parent2845b656a3ed058bc424ca371760fb17b2a28703 (diff)
downloadmariadb-git-f81eef62e7742806e5e74b5f37f35b7cd2f82291.tar.gz
MDEV-24117: Memory management problem in statistics state for ... IN
Part#1: Revert the patch that caused it: commit 291be494744abe90f4bdf6b5a35c4c26ee8ddda5 Author: Igor Babaev <igor@askmonty.org> Date: Thu Sep 24 22:02:00 2020 -0700 MDEV-23811: With large number of indexes optimizer chooses an inefficient plan
-rw-r--r--mysql-test/r/range.result74
-rw-r--r--mysql-test/r/range_mrr_icp.result74
-rw-r--r--mysql-test/r/range_vs_index_merge_innodb.result2
-rw-r--r--mysql-test/t/range.test42
-rw-r--r--sql/opt_range.cc20
5 files changed, 11 insertions, 201 deletions
diff --git a/mysql-test/r/range.result b/mysql-test/r/range.result
index 7299982e72d..26ea2c6d323 100644
--- a/mysql-test/r/range.result
+++ b/mysql-test/r/range.result
@@ -1274,7 +1274,7 @@ SELECT * FROM t1 WHERE
5 <= a AND b = 3 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
@@ -3054,77 +3054,5 @@ a b
set eq_range_index_dive_limit=default;
drop table t1;
#
-# MDEV-23811: Both disjunct of WHERE condition contain range conditions
-# for the same index such that the second range condition
-# fully covers the first one. Additionally one of the disjuncts
-# contains a range condition for the other index.
-#
-create table t1 (
-pk int primary key auto_increment, a int, b int,
-index idx1(a), index idx2(b)
-);
-insert into t1(a,b) values
-(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
-insert into t1(a,b) select a+10, b+100 from t1;
-insert into t1(a,b) select a+20, b+200 from t1;
-insert into t1(a,b) select a+30, b+300 from t1;
-insert into t1(a,b) select a,b from t1;
-analyze table t1;
-Table Op Msg_type Msg_text
-test.t1 analyze status OK
-explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
-select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
-pk a b
-7 2 20
-71 2 20
-3 3 30
-67 3 30
-6 4 40
-70 4 40
-1 5 50
-65 5 50
-explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
-select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
-pk a b
-7 2 20
-71 2 20
-3 3 30
-67 3 30
-6 4 40
-70 4 40
-1 5 50
-65 5 50
-explain select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
-select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
-pk a b
-7 2 20
-71 2 20
-3 3 30
-67 3 30
-6 4 40
-70 4 40
-1 5 50
-65 5 50
-explain select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where
-select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
-pk a b
-7 2 20
-71 2 20
-3 3 30
-67 3 30
-6 4 40
-70 4 40
-1 5 50
-65 5 50
-drop table t1;
-#
# End of 10.2 tests
#
diff --git a/mysql-test/r/range_mrr_icp.result b/mysql-test/r/range_mrr_icp.result
index cdaaa5e8ab7..fe4eb99f31f 100644
--- a/mysql-test/r/range_mrr_icp.result
+++ b/mysql-test/r/range_mrr_icp.result
@@ -1276,7 +1276,7 @@ SELECT * FROM t1 WHERE
5 <= a AND b = 3 OR
3 <= a;
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range a a 5 NULL 3 Using where; Using index
+1 SIMPLE t1 range a a 5 NULL 4 Using where; Using index
SELECT * FROM t1 WHERE
3 <= a AND a <= 5 OR
5 <= a AND b = 3 OR
@@ -3066,78 +3066,6 @@ a b
set eq_range_index_dive_limit=default;
drop table t1;
#
-# MDEV-23811: Both disjunct of WHERE condition contain range conditions
-# for the same index such that the second range condition
-# fully covers the first one. Additionally one of the disjuncts
-# contains a range condition for the other index.
-#
-create table t1 (
-pk int primary key auto_increment, a int, b int,
-index idx1(a), index idx2(b)
-);
-insert into t1(a,b) values
-(5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
-insert into t1(a,b) select a+10, b+100 from t1;
-insert into t1(a,b) select a+20, b+200 from t1;
-insert into t1(a,b) select a+30, b+300 from t1;
-insert into t1(a,b) select a,b from t1;
-analyze table t1;
-Table Op Msg_type Msg_text
-test.t1 analyze status OK
-explain select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
-select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
-pk a b
-1 5 50
-3 3 30
-6 4 40
-7 2 20
-65 5 50
-67 3 30
-70 4 40
-71 2 20
-explain select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
-select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
-pk a b
-1 5 50
-3 3 30
-6 4 40
-7 2 20
-65 5 50
-67 3 30
-70 4 40
-71 2 20
-explain select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
-select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
-pk a b
-1 5 50
-3 3 30
-6 4 40
-7 2 20
-65 5 50
-67 3 30
-70 4 40
-71 2 20
-explain select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
-id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE t1 range idx1,idx2 idx1 5 NULL 11 Using index condition; Using where; Rowid-ordered scan
-select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
-pk a b
-1 5 50
-3 3 30
-6 4 40
-7 2 20
-65 5 50
-67 3 30
-70 4 40
-71 2 20
-drop table t1;
-#
# End of 10.2 tests
#
set optimizer_switch=@mrr_icp_extra_tmp;
diff --git a/mysql-test/r/range_vs_index_merge_innodb.result b/mysql-test/r/range_vs_index_merge_innodb.result
index 916c30bb770..581f512768c 100644
--- a/mysql-test/r/range_vs_index_merge_innodb.result
+++ b/mysql-test/r/range_vs_index_merge_innodb.result
@@ -369,7 +369,7 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 200) AND
(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
id select_type table type possible_keys key key_len ref rows Extra
-1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 200 Using where
+1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Population,PRIMARY 39,4,4 NULL 307 Using sort_union(Name,Population,PRIMARY); Using where
SELECT * FROM City USE INDEX ()
WHERE ((ID < 10) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
OR ((ID BETWEEN 100 AND 110) AND
diff --git a/mysql-test/t/range.test b/mysql-test/t/range.test
index 0d2fbe24835..67d876d5f10 100644
--- a/mysql-test/t/range.test
+++ b/mysql-test/t/range.test
@@ -2096,48 +2096,6 @@ set eq_range_index_dive_limit=default;
drop table t1;
--echo #
---echo # MDEV-23811: Both disjunct of WHERE condition contain range conditions
---echo # for the same index such that the second range condition
---echo # fully covers the first one. Additionally one of the disjuncts
---echo # contains a range condition for the other index.
---echo #
-
-create table t1 (
- pk int primary key auto_increment, a int, b int,
- index idx1(a), index idx2(b)
-);
-insert into t1(a,b) values
- (5,50), (1,10), (3,30), (7,70), (8,80), (4,40), (2,20), (6,60);
-insert into t1(a,b) select a+10, b+100 from t1;
-insert into t1(a,b) select a+20, b+200 from t1;
-insert into t1(a,b) select a+30, b+300 from t1;
-insert into t1(a,b) select a,b from t1;
-
-analyze table t1;
-
-let $q1=
-select * from t1 where ((a between 3 and 4) and b < 100) or (a between 2 and 5);
-eval explain $q1;
-eval $q1;
-
-let $q2=
-select * from t1 where (a between 2 and 5) or ((a between 3 and 4) and b < 100);
-eval explain $q2;
-eval $q2;
-
-let $q3=
-select * from t1 where (a between 3 and 4) or ((a between 2 and 5) and b < 100);
-eval explain $q3;
-eval $q3;
-
-let $q4=
-select * from t1 where ((a between 2 and 5) and b < 100) or (a between 3 and 4);
-eval explain $q4;
-eval $q4;
-
-drop table t1;
-
---echo #
--echo # End of 10.2 tests
--echo #
diff --git a/sql/opt_range.cc b/sql/opt_range.cc
index cd58202ef5f..e933d2af355 100644
--- a/sql/opt_range.cc
+++ b/sql/opt_range.cc
@@ -1852,9 +1852,6 @@ SEL_ARG::SEL_ARG(SEL_ARG &arg) :Sql_alloc()
next_key_part=arg.next_key_part;
max_part_no= arg.max_part_no;
use_count=1; elements=1;
- next= 0;
- if (next_key_part)
- ++next_key_part->use_count;
}
@@ -8872,15 +8869,9 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
}
bool no_imerge_from_ranges= FALSE;
- SEL_TREE *rt1= tree1;
- SEL_TREE *rt2= tree2;
/* Build the range part of the tree for the formula (1) */
if (sel_trees_can_be_ored(param, tree1, tree2, &ored_keys))
{
- if (no_merges1)
- rt1= new SEL_TREE(tree1, TRUE, param);
- if (no_merges2)
- rt2= new SEL_TREE(tree2, TRUE, param);
bool must_be_ored= sel_trees_must_be_ored(param, tree1, tree2, ored_keys);
no_imerge_from_ranges= must_be_ored;
@@ -8938,6 +8929,12 @@ tree_or(RANGE_OPT_PARAM *param,SEL_TREE *tree1,SEL_TREE *tree2)
else if (!no_ranges1 && !no_ranges2 && !no_imerge_from_ranges)
{
/* Build the imerge part of the tree for the formula (1) */
+ SEL_TREE *rt1= tree1;
+ SEL_TREE *rt2= tree2;
+ if (no_merges1)
+ rt1= new SEL_TREE(tree1, TRUE, param);
+ if (no_merges2)
+ rt2= new SEL_TREE(tree2, TRUE, param);
if (!rt1 || !rt2 ||
result->merges.push_back(imerge_from_ranges) ||
imerge_from_ranges->or_sel_tree(param, rt1) ||
@@ -9600,11 +9597,10 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
if (!tmp->next_key_part)
{
- SEL_ARG *key2_next= key2->next;
if (key2->use_count)
{
SEL_ARG *key2_cpy= new SEL_ARG(*key2);
- if (!key2_cpy)
+ if (key2_cpy)
return 0;
key2= key2_cpy;
}
@@ -9625,7 +9621,7 @@ key_or(RANGE_OPT_PARAM *param, SEL_ARG *key1,SEL_ARG *key2)
Move on to next range in key2
*/
key2->increment_use_count(-1); // Free not used tree
- key2=key2_next;
+ key2=key2->next;
continue;
}
else