Commit f874071a authored by sergefp@mysql.com's avatar sergefp@mysql.com

Range optimizer fix:

If cost(full_scan_on_shortest_covering_index) < cost(best_range_scan) <  cost(full_table_scan)
  use full_scan_on_shortest_covering_index
(before this fix best_range_scan was used)
parent 7a9f4c6a
...@@ -53,10 +53,10 @@ create table t1 (a varchar(10) character set ucs2, key(a)); ...@@ -53,10 +53,10 @@ create table t1 (a varchar(10) character set ucs2, key(a));
insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
explain select * from t1 where a like 'abc%'; explain select * from t1 where a like 'abc%';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 21 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 21 NULL 5 Using where; Using index
explain select * from t1 where a like concat('abc','%'); explain select * from t1 where a like concat('abc','%');
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 21 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 21 NULL 5 Using where; Using index
select * from t1 where a like "abc%"; select * from t1 where a like "abc%";
a a
abc abc
......
...@@ -318,11 +318,11 @@ create table t2 (a int, b int, primary key (a)); ...@@ -318,11 +318,11 @@ create table t2 (a int, b int, primary key (a));
insert into t2 values (1,7),(2,7); insert into t2 values (1,7),(2,7);
explain select a from t2 where a>1; explain select a from t2 where a>1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index 1 SIMPLE t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
explain select a from (select a from t2 where a>1) tt; explain select a from (select a from t2 where a>1) tt;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 PRIMARY <derived2> system NULL NULL NULL NULL 1 1 PRIMARY <derived2> system NULL NULL NULL NULL 1
2 DERIVED t2 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index 2 DERIVED t2 index PRIMARY PRIMARY 4 NULL 2 Using where; Using index
drop table t2; drop table t2;
CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`)); CREATE TABLE `t1` ( `itemid` int(11) NOT NULL default '0', `grpid` varchar(15) NOT NULL default '', `vendor` int(11) NOT NULL default '0', `date_` date NOT NULL default '0000-00-00', `price` decimal(12,2) NOT NULL default '0.00', PRIMARY KEY (`itemid`,`grpid`,`vendor`,`date_`), KEY `itemid` (`itemid`,`vendor`), KEY `itemid_2` (`itemid`,`date_`));
insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10); insert into t1 values (128, 'rozn', 2, now(), 10),(128, 'rozn', 1, now(), 10);
......
...@@ -572,11 +572,11 @@ AME AME ...@@ -572,11 +572,11 @@ AME AME
explain explain
select min(a1) from t1 where a1 > 'KKK' or a1 < 'XXX'; select min(a1) from t1 where a1 > 'KKK' or a1 < 'XXX';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 0 NULL 15 Using where; Using index 1 SIMPLE t1 index PRIMARY PRIMARY 3 NULL 14 Using where; Using index
explain explain
select min(a1) from t1 where a1 != 'KKK'; select min(a1) from t1 where a1 != 'KKK';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 3 NULL 14 Using where; Using index 1 SIMPLE t1 index PRIMARY PRIMARY 3 NULL 14 Using where; Using index
explain explain
select max(a3) from t1 where a2 < 2 and a3 < 'SEA'; select max(a3) from t1 where a2 < 2 and a3 < 'SEA';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
...@@ -584,7 +584,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -584,7 +584,7 @@ id select_type table type possible_keys key key_len ref rows Extra
explain explain
select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA'; select max(t1.a3), min(t2.a2) from t1, t2 where t1.a2 = 2 and t1.a3 < 'MIN' and t2.a3 > 'CA';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range k1 k1 7 NULL 1 Using where; Using index 1 SIMPLE t1 ref k1 k1 3 const 2 Using where; Using index
1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index 1 SIMPLE t2 range k1 k1 3 NULL 4 Using where; Using index
explain explain
select min(a4 - 0.01) from t1; select min(a4 - 0.01) from t1;
......
...@@ -3,10 +3,10 @@ create table t1 (a varchar(10), key(a)); ...@@ -3,10 +3,10 @@ create table t1 (a varchar(10), key(a));
insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test"); insert into t1 values ("a"),("abc"),("abcd"),("hello"),("test");
explain select * from t1 where a like 'abc%'; explain select * from t1 where a like 'abc%';
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 11 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 11 NULL 5 Using where; Using index
explain select * from t1 where a like concat('abc','%'); explain select * from t1 where a like concat('abc','%');
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 11 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 11 NULL 5 Using where; Using index
select * from t1 where a like "abc%"; select * from t1 where a like "abc%";
a a
abc abc
......
...@@ -66,7 +66,7 @@ a ...@@ -66,7 +66,7 @@ a
alter table t1 engine=myisam; alter table t1 engine=myisam;
explain select * from t1 where a in (869751,736494,226312,802616); explain select * from t1 where a in (869751,736494,226312,802616);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index 1 SIMPLE t1 index uniq_id uniq_id 4 NULL 4 Using where; Using index
drop table t1; drop table t1;
create table t1 (x int not null, y int not null, key x (x), unique y (y)) create table t1 (x int not null, y int not null, key x (x), unique y (y))
engine=heap; engine=heap;
......
...@@ -66,7 +66,7 @@ a ...@@ -66,7 +66,7 @@ a
alter table t1 engine=myisam; alter table t1 engine=myisam;
explain select * from t1 where a in (869751,736494,226312,802616); explain select * from t1 where a in (869751,736494,226312,802616);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index 1 SIMPLE t1 index uniq_id uniq_id 4 NULL 4 Using where; Using index
drop table t1; drop table t1;
create table t1 (x int not null, y int not null, key x using BTREE (x,y), unique y using BTREE (y)) create table t1 (x int not null, y int not null, key x using BTREE (x,y), unique y using BTREE (y))
engine=heap; engine=heap;
......
...@@ -66,7 +66,7 @@ a ...@@ -66,7 +66,7 @@ a
alter table t1 engine=myisam; alter table t1 engine=myisam;
explain select * from t1 where a in (869751,736494,226312,802616); explain select * from t1 where a in (869751,736494,226312,802616);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range uniq_id uniq_id 4 NULL 4 Using where; Using index 1 SIMPLE t1 index uniq_id uniq_id 4 NULL 4 Using where; Using index
drop table t1; drop table t1;
create table t1 (x int not null, y int not null, key x using HASH (x), unique y using HASH (y)) create table t1 (x int not null, y int not null, key x using HASH (x), unique y using HASH (y))
engine=heap; engine=heap;
......
...@@ -634,7 +634,7 @@ insert into t2 values (10,1),(20,2),(30,3); ...@@ -634,7 +634,7 @@ insert into t2 values (10,1),(20,2),(30,3);
explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; explain select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index 1 SIMPLE t2 index NULL PRIMARY 4 NULL 3 Using index
1 SIMPLE t1 eq_ref PRIMARY PRIMARY 2 const 1 Using where; Using index 1 SIMPLE t1 eq_ref PRIMARY PRIMARY 2 const 1 Using index
select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30; select * from t2 left join t1 on t1.fooID = t2.fooID and t1.fooID = 30;
fooID barID fooID fooID barID fooID
10 1 NULL 10 1 NULL
......
...@@ -213,14 +213,14 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -213,14 +213,14 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 Using index
explain select 1 from t1 where id =2 or id=3; explain select 1 from t1 where id =2 or id=3;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range PRIMARY PRIMARY 4 NULL 2 Using where; Using index 1 SIMPLE t1 index PRIMARY PRIMARY 4 NULL 7 Using where; Using index
explain select name from t1 where id =2; explain select name from t1 where id =2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1 1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
ALTER TABLE t1 DROP PRIMARY KEY, ADD INDEX (id); ALTER TABLE t1 DROP PRIMARY KEY, ADD INDEX (id);
explain select 1 from t1 where id =2; explain select 1 from t1 where id =2;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref id id 4 const 1 Using where; Using index 1 SIMPLE t1 ref id id 4 const 1 Using index
drop table t1; drop table t1;
CREATE TABLE t1 (numeropost mediumint(8) unsigned NOT NULL default '0', numreponse int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (numeropost,numreponse), UNIQUE KEY numreponse (numreponse)); CREATE TABLE t1 (numeropost mediumint(8) unsigned NOT NULL default '0', numreponse int(10) unsigned NOT NULL auto_increment, PRIMARY KEY (numeropost,numreponse), UNIQUE KEY numreponse (numreponse));
INSERT INTO t1 (numeropost,numreponse) VALUES ('1','1'),('1','2'),('2','3'),('2','4'); INSERT INTO t1 (numeropost,numreponse) VALUES ('1','1'),('1','2'),('2','3'),('2','4');
......
...@@ -30,13 +30,13 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -30,13 +30,13 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index 1 SIMPLE t1 ref a,b a 5 const 3 Using where; Using index
explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3; explain select * from t1 where a is null and b=9 or a is null and b=7 limit 3;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a,b a 9 NULL 2 Using where; Using index 1 SIMPLE t1 ref a,b a 5 const 2 Using where; Using index
explain select * from t1 where a > 1 and a < 3 limit 1; explain select * from t1 where a > 1 and a < 3 limit 1;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 9 NULL 12 Using where; Using index
explain select * from t1 where a > 8 and a < 9; explain select * from t1 where a > 8 and a < 9;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 5 NULL 1 Using where; Using index 1 SIMPLE t1 index a a 9 NULL 12 Using where; Using index
select * from t1 where a is null; select * from t1 where a is null;
a b a b
NULL 7 NULL 7
......
...@@ -272,7 +272,7 @@ create table t1 (a int not null, b int, c varchar(10), key (a, b, c)); ...@@ -272,7 +272,7 @@ create table t1 (a int not null, b int, c varchar(10), key (a, b, c));
insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b'); insert into t1 values (1, NULL, NULL), (1, NULL, 'b'), (1, 1, NULL), (1, 1, 'b'), (1, 1, 'b'), (2, 1, 'a'), (2, 1, 'b'), (2, 2, 'a'), (2, 2, 'b'), (2, 3, 'c'),(1,3,'b');
explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; explain select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 20 NULL 2 Using where; Using index 1 SIMPLE t1 index a a 20 NULL 11 Using where; Using index
select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc; select * from t1 where (a = 1 and b is null and c = 'b') or (a > 2) order by a desc;
a b c a b c
1 NULL b 1 NULL b
...@@ -328,7 +328,7 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -328,7 +328,7 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index 1 SIMPLE t1 range a a 9 NULL 5 Using where; Using index
explain select * from t1 where a = 2 and b < 2 order by a desc,b desc; explain select * from t1 where a = 2 and b < 2 order by a desc,b desc;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range a a 9 NULL 2 Using where; Using index 1 SIMPLE t1 ref a a 4 const 2 Using where; Using index
explain select * from t1 where a = 1 order by b desc; explain select * from t1 where a = 1 order by b desc;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 ref a a 4 const 5 Using where; Using index 1 SIMPLE t1 ref a a 4 const 5 Using where; Using index
......
...@@ -244,10 +244,10 @@ id select_type table type possible_keys key key_len ref rows Extra ...@@ -244,10 +244,10 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range x x 5 NULL 2 Using where 1 SIMPLE t2 range x x 5 NULL 2 Using where
explain select count(*) from t1 where x in (1); explain select count(*) from t1 where x in (1);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range x x 5 NULL 1 Using where; Using index 1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
explain select count(*) from t1 where x in (1,2); explain select count(*) from t1 where x in (1,2);
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range x x 5 NULL 2 Using where; Using index 1 SIMPLE t1 index x x 5 NULL 9 Using where; Using index
drop table t1; drop table t1;
CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1)); CREATE TABLE t1 (key1 int(11) NOT NULL default '0', KEY i1 (key1));
INSERT INTO t1 VALUES (0),(0),(1),(1); INSERT INTO t1 VALUES (0),(0),(1),(1);
...@@ -255,7 +255,7 @@ CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya)); ...@@ -255,7 +255,7 @@ CREATE TABLE t2 (keya int(11) NOT NULL default '0', KEY j1 (keya));
INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2); INSERT INTO t2 VALUES (0),(0),(1),(1),(2),(2);
explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3; explain select * from t1, t2 where (t1.key1 <t2.keya + 1) and t2.keya=3;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 ref j1 j1 4 const 1 Using where; Using index 1 SIMPLE t2 ref j1 j1 4 const 1 Using index
1 SIMPLE t1 ALL i1 NULL NULL NULL 4 Range checked for each record (index map: 0x1) 1 SIMPLE t1 ALL i1 NULL NULL NULL 4 Range checked for each record (index map: 0x1)
DROP TABLE t1,t2; DROP TABLE t1,t2;
CREATE TABLE t1 ( CREATE TABLE t1 (
......
...@@ -2150,10 +2150,10 @@ a a a ...@@ -2150,10 +2150,10 @@ a a a
select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1; select * from (t1 as t2 left join t1 as t3 using (a)) inner join t1 on t1.a>1;
a a a a a a
1 1 2 1 1 2
1 1 3
2 2 2 2 2 2
2 2 3
3 3 2 3 3 2
1 1 3
2 2 3
3 3 3 3 3 3
select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; select * from t1 inner join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1;
a a a a a a
......
...@@ -1614,6 +1614,17 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, ...@@ -1614,6 +1614,17 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
} }
param.key_parts_end=key_parts; param.key_parts_end=key_parts;
/* Calculate cost of full index read for the shortest covering index */
if (!head->used_keys.is_clear_all())
{
int key_for_use= find_shortest_key(head, &head->used_keys);
double key_read_time= get_index_only_read_time(&param, records,
key_for_use);
DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, "
"read time %g", key_for_use, key_read_time));
if (key_read_time < read_time)
read_time= key_read_time;
}
if ((tree=get_mm_tree(&param,cond))) if ((tree=get_mm_tree(&param,cond)))
{ {
...@@ -1676,17 +1687,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use, ...@@ -1676,17 +1687,6 @@ int SQL_SELECT::test_quick_select(THD *thd, key_map keys_to_use,
TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp; TABLE_READ_PLAN *best_conj_trp= NULL, *new_conj_trp;
LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */ LINT_INIT(new_conj_trp); /* no empty index_merge lists possible */
/* Calculate cost of full index read for the shortest covering index */
if (!head->used_keys.is_clear_all())
{
int key_for_use= find_shortest_key(head, &head->used_keys);
double key_read_time= get_index_only_read_time(&param, records,
key_for_use);
DBUG_PRINT("info", ("'all'+'using index' scan will be using key %d, "
"read time %g", key_for_use, key_read_time));
if (key_read_time < read_time)
read_time= key_read_time;
}
DBUG_PRINT("info",("No range reads possible," DBUG_PRINT("info",("No range reads possible,"
" trying to construct index_merge")); " trying to construct index_merge"));
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment