mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
WL#3527: Extend IGNORE INDEX so places where index is ignored
can be specified Currently MySQL allows one to specify what indexes to ignore during join optimization. The scope of the current USE/FORCE/IGNORE INDEX statement is only the FROM clause, while all other clauses are not affected. However, in certain cases, the optimizer may incorrectly choose an index for sorting and/or grouping, and produce an inefficient query plan. This task provides the means to specify what indexes are ignored/used for what operation in a more fine-grained manner, thus making it possible to manually force a better plan. We do this by extending the current IGNORE/USE/FORCE INDEX syntax to: IGNORE/USE/FORCE INDEX [FOR {JOIN | ORDER | GROUP BY}] so that: - if no FOR is specified, the index hint will apply everywhere. - if MySQL is started with the compatibility option --old_mode then an index hint without a FOR clause works as in 5.0 (i.e, the index will only be ignored for JOINs, but can still be used to compute ORDER BY). See the WL#3527 for further details.
This commit is contained in:
@ -25,10 +25,11 @@ insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
text1
|
||||
teststring
|
||||
teststring
|
||||
teststring
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
text1
|
||||
teststring
|
||||
@ -48,10 +49,11 @@ alter table t1 modify text1 char(32) binary not null;
|
||||
check table t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
text1
|
||||
teststring
|
||||
teststring
|
||||
teststring
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
concat('|', text1, '|')
|
||||
|teststring |
|
||||
@ -132,10 +134,11 @@ concat('|', text1, '|')
|
||||
drop table t1;
|
||||
create table t1 (text1 varchar(32) not NULL, KEY key1 using BTREE (text1)) engine=heap;
|
||||
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
text1
|
||||
teststring
|
||||
teststring
|
||||
teststring
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
text1
|
||||
teststring
|
||||
|
@ -933,12 +933,110 @@ b sum(1)
|
||||
18 6
|
||||
19 6
|
||||
DROP TABLE t1;
|
||||
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2;
|
||||
CREATE TABLE t1 (a INT, b INT,
|
||||
PRIMARY KEY (a),
|
||||
KEY i2(a,b));
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
|
||||
INSERT INTO t1 SELECT a + 8,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 128,b FROM t1;
|
||||
ANALYZE TABLE t1;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status OK
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL a 5 NULL 4
|
||||
EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2;
|
||||
1 SIMPLE t1 range PRIMARY,i2 PRIMARY 4 NULL 2 Using where; Using index
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2 ORDER BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
|
||||
DROP TABLE t1;
|
||||
1 SIMPLE t1 range PRIMARY,i2 PRIMARY 4 NULL 2 Using where; Using index
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2 GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range PRIMARY,i2 PRIMARY 4 NULL 2 Using where; Using index
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY,i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR JOIN (PRIMARY,i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR GROUP BY (PRIMARY,i2) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY,i2) ORDER BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY)
|
||||
IGNORE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL PRIMARY 4 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY) IGNORE INDEX FOR ORDER BY (i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX (i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX ();
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX () USE INDEX (i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1
|
||||
FORCE INDEX (PRIMARY)
|
||||
IGNORE INDEX FOR GROUP BY (i2)
|
||||
IGNORE INDEX FOR ORDER BY (i2)
|
||||
USE INDEX (i2);
|
||||
ERROR HY000: Incorrect usage of USE INDEX and FORCE INDEX
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX (i2) USE INDEX ();
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX ();
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX ();
|
||||
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX FOR JOIN (i2)
|
||||
FORCE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 range NULL i2 4 NULL 257 Using index for group-by
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX () IGNORE INDEX (i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (i2) USE INDEX ();
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ALL NULL NULL NULL NULL 256
|
||||
EXPLAIN SELECT a FROM t1
|
||||
USE INDEX FOR GROUP BY (i2)
|
||||
USE INDEX FOR ORDER BY (i2)
|
||||
USE INDEX FOR JOIN (i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT a FROM t1
|
||||
USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR JOIN (i2,i2);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 index NULL i2 9 NULL 256 Using index
|
||||
EXPLAIN SELECT 1 FROM t1 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t1 index NULL PRIMARY 4 NULL 256 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 256 Using where
|
||||
CREATE TABLE t2 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 index NULL a 5 NULL 4
|
||||
EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL NULL NULL NULL NULL 4 Using temporary; Using filesort
|
||||
EXPLAIN SELECT 1 FROM t2 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index
|
||||
2 DEPENDENT SUBQUERY t1 ALL NULL NULL NULL NULL 256 Using where
|
||||
DROP TABLE t1, t2;
|
||||
|
@ -16,7 +16,8 @@ drop table if exists t1;
|
||||
create table t1 (text1 varchar(32) not NULL, KEY key1 (text1));
|
||||
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
|
||||
check table t1;
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select * from t1 order by text1;
|
||||
@ -24,7 +25,8 @@ explain select * from t1 order by text1;
|
||||
|
||||
alter table t1 modify text1 char(32) binary not null;
|
||||
check table t1;
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select concat('|', text1, '|') from t1 where text1='teststring' or text1 > 'teststring\t';
|
||||
select text1, length(text1) from t1 order by text1;
|
||||
@ -57,7 +59,8 @@ drop table t1;
|
||||
|
||||
create table t1 (text1 varchar(32) not NULL, KEY key1 using BTREE (text1)) engine=heap;
|
||||
insert into t1 values ('teststring'), ('nothing'), ('teststring\t');
|
||||
select * from t1 ignore key (key1) where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 ignore key (key1) where text1='teststring' or
|
||||
text1 like 'teststring_%' ORDER BY text1;
|
||||
select * from t1 where text1='teststring' or text1 like 'teststring_%';
|
||||
select * from t1 where text1='teststring' or text1 >= 'teststring\t';
|
||||
select * from t1 order by text1;
|
||||
|
@ -706,10 +706,66 @@ DROP TABLE t1;
|
||||
# Bug #21174: Index degrades sort performance and
|
||||
# optimizer does not honor IGNORE INDEX
|
||||
#
|
||||
CREATE TABLE t1 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t1 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
CREATE TABLE t1 (a INT, b INT,
|
||||
PRIMARY KEY (a),
|
||||
KEY i2(a,b));
|
||||
INSERT INTO t1 VALUES (1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8);
|
||||
INSERT INTO t1 SELECT a + 8,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 16,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 32,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 64,b FROM t1;
|
||||
INSERT INTO t1 SELECT a + 128,b FROM t1;
|
||||
ANALYZE TABLE t1;
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2;
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2 ORDER BY a;
|
||||
EXPLAIN SELECT a FROM t1 WHERE a < 2 GROUP BY a;
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY,i2);
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR JOIN (PRIMARY,i2);
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR GROUP BY (PRIMARY,i2) GROUP BY a;
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY,i2) ORDER BY a;
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX FOR ORDER BY (PRIMARY)
|
||||
IGNORE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (PRIMARY) IGNORE INDEX FOR ORDER BY (i2);
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX (i2);
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX ();
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX () USE INDEX (i2);
|
||||
--error ER_WRONG_USAGE
|
||||
EXPLAIN SELECT a FROM t1
|
||||
FORCE INDEX (PRIMARY)
|
||||
IGNORE INDEX FOR GROUP BY (i2)
|
||||
IGNORE INDEX FOR ORDER BY (i2)
|
||||
USE INDEX (i2);
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX (i2) USE INDEX ();
|
||||
--error ER_PARSE_ERROR
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX ();
|
||||
--error ER_PARSE_ERROR
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX ();
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
EXPLAIN SELECT a FROM t1 FORCE INDEX FOR JOIN (i2)
|
||||
FORCE INDEX FOR GROUP BY (i2) GROUP BY a;
|
||||
EXPLAIN SELECT a FROM t1 USE INDEX () IGNORE INDEX (i2);
|
||||
EXPLAIN SELECT a FROM t1 IGNORE INDEX (i2) USE INDEX ();
|
||||
|
||||
EXPLAIN SELECT a, SUM(b) FROM t1 GROUP BY a LIMIT 2;
|
||||
EXPLAIN SELECT a, SUM(b) FROM t1 IGNORE INDEX (a) GROUP BY a LIMIT 2;
|
||||
EXPLAIN SELECT a FROM t1
|
||||
USE INDEX FOR GROUP BY (i2)
|
||||
USE INDEX FOR ORDER BY (i2)
|
||||
USE INDEX FOR JOIN (i2);
|
||||
|
||||
DROP TABLE t1;
|
||||
EXPLAIN SELECT a FROM t1
|
||||
USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR JOIN (i2)
|
||||
USE INDEX FOR JOIN (i2,i2);
|
||||
|
||||
EXPLAIN SELECT 1 FROM t1 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
|
||||
CREATE TABLE t2 (a INT, b INT, KEY(a));
|
||||
INSERT INTO t2 VALUES (1, 1), (2, 2), (3,3), (4,4);
|
||||
EXPLAIN SELECT a, SUM(b) FROM t2 GROUP BY a LIMIT 2;
|
||||
EXPLAIN SELECT a, SUM(b) FROM t2 IGNORE INDEX (a) GROUP BY a LIMIT 2;
|
||||
|
||||
EXPLAIN SELECT 1 FROM t2 WHERE a IN
|
||||
(SELECT a FROM t1 USE INDEX (i2) IGNORE INDEX (i2));
|
||||
|
||||
DROP TABLE t1, t2;
|
||||
|
Reference in New Issue
Block a user