Fixed the bug mdev-11574.
Do not build an index merge of two indexes when one index is an infix of the other index.
This commit is contained in:
parent
e6862cf1ff
commit
dbeffabc83
@ -1807,4 +1807,85 @@ id state capital
|
|||||||
7 Pennsylvania Harrisburg
|
7 Pennsylvania Harrisburg
|
||||||
8 Virginia Richmond
|
8 Virginia Richmond
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# mdev-11574: do not build index merge of two indexes when
|
||||||
|
# one index is an infix of the other index
|
||||||
|
#
|
||||||
|
set names utf8;
|
||||||
|
CREATE DATABASE world;
|
||||||
|
use world;
|
||||||
|
CREATE TABLE Country (
|
||||||
|
Code char(3) NOT NULL default '',
|
||||||
|
Name char(52) NOT NULL default '',
|
||||||
|
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||||
|
Population int(11) NOT NULL default '0',
|
||||||
|
Capital int(11) default NULL,
|
||||||
|
PRIMARY KEY (Code),
|
||||||
|
UNIQUE INDEX (Name)
|
||||||
|
);
|
||||||
|
CREATE TABLE City (
|
||||||
|
ID int(11) NOT NULL auto_increment,
|
||||||
|
Name char(35) NOT NULL default '',
|
||||||
|
Country char(3) NOT NULL default '',
|
||||||
|
Population int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
INDEX (Population),
|
||||||
|
INDEX (Country)
|
||||||
|
);
|
||||||
|
CREATE TABLE CountryLanguage (
|
||||||
|
Country char(3) NOT NULL default '',
|
||||||
|
Language char(30) NOT NULL default '',
|
||||||
|
Percentage float(3,1) NOT NULL default '0.0',
|
||||||
|
PRIMARY KEY (Country, Language),
|
||||||
|
INDEX (Percentage)
|
||||||
|
);
|
||||||
|
DROP INDEX Country ON City;
|
||||||
|
CREATE INDEX CountryName ON City(Country,Name);
|
||||||
|
CREATE INDEX Name ON City(Name);
|
||||||
|
select * from City
|
||||||
|
where
|
||||||
|
Country='FIN' AND Name IN ('Lahti','Imatra') OR
|
||||||
|
Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
|
||||||
|
Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
|
||||||
|
Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
|
||||||
|
Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
|
||||||
|
Country='PRT' AND Name IN ('Braga', 'Porto') OR
|
||||||
|
Country='FRA' AND Name IN ('Paris', 'Marcel') OR
|
||||||
|
Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
|
||||||
|
Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
|
||||||
|
Country='ITA' AND Name IN ('Napoli', 'Venezia');
|
||||||
|
ID Name Country Population
|
||||||
|
175 Antwerpen BEL 446525
|
||||||
|
176 Gent BEL 224180
|
||||||
|
3068 Berlin DEU 3386667
|
||||||
|
3087 Bonn DEU 301048
|
||||||
|
3242 Lahti FIN 96921
|
||||||
|
2974 Paris FRA 2125246
|
||||||
|
1466 Napoli ITA 1002619
|
||||||
|
1474 Venezia ITA 277305
|
||||||
|
2808 Bergen NOR 230948
|
||||||
|
2807 Oslo NOR 508726
|
||||||
|
2928 Warszawa POL 1615369
|
||||||
|
2931 Wroclaw POL 636765
|
||||||
|
2918 Braga PRT 90535
|
||||||
|
2915 Porto PRT 273060
|
||||||
|
3580 Moscow RUS 8389200
|
||||||
|
3581 St Petersburg RUS 4694000
|
||||||
|
3048 Stockholm SWE 750348
|
||||||
|
3051 Uppsala SWE 189569
|
||||||
|
explain select * from City
|
||||||
|
where
|
||||||
|
Country='FIN' AND Name IN ('Lahti','Imatra') OR
|
||||||
|
Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
|
||||||
|
Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
|
||||||
|
Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
|
||||||
|
Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
|
||||||
|
Country='PRT' AND Name IN ('Braga', 'Porto') OR
|
||||||
|
Country='FRA' AND Name IN ('Paris', 'Marcel') OR
|
||||||
|
Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
|
||||||
|
Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
|
||||||
|
Country='ITA' AND Name IN ('Napoli', 'Venezia');
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE City range CountryName,Name CountryName 38 NULL 22 Using index condition; Using where
|
||||||
|
DROP DATABASE world;
|
||||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||||
|
@ -1808,5 +1808,86 @@ id state capital
|
|||||||
7 Pennsylvania Harrisburg
|
7 Pennsylvania Harrisburg
|
||||||
8 Virginia Richmond
|
8 Virginia Richmond
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
#
|
||||||
|
# mdev-11574: do not build index merge of two indexes when
|
||||||
|
# one index is an infix of the other index
|
||||||
|
#
|
||||||
|
set names utf8;
|
||||||
|
CREATE DATABASE world;
|
||||||
|
use world;
|
||||||
|
CREATE TABLE Country (
|
||||||
|
Code char(3) NOT NULL default '',
|
||||||
|
Name char(52) NOT NULL default '',
|
||||||
|
SurfaceArea float(10,2) NOT NULL default '0.00',
|
||||||
|
Population int(11) NOT NULL default '0',
|
||||||
|
Capital int(11) default NULL,
|
||||||
|
PRIMARY KEY (Code),
|
||||||
|
UNIQUE INDEX (Name)
|
||||||
|
);
|
||||||
|
CREATE TABLE City (
|
||||||
|
ID int(11) NOT NULL auto_increment,
|
||||||
|
Name char(35) NOT NULL default '',
|
||||||
|
Country char(3) NOT NULL default '',
|
||||||
|
Population int(11) NOT NULL default '0',
|
||||||
|
PRIMARY KEY (ID),
|
||||||
|
INDEX (Population),
|
||||||
|
INDEX (Country)
|
||||||
|
);
|
||||||
|
CREATE TABLE CountryLanguage (
|
||||||
|
Country char(3) NOT NULL default '',
|
||||||
|
Language char(30) NOT NULL default '',
|
||||||
|
Percentage float(3,1) NOT NULL default '0.0',
|
||||||
|
PRIMARY KEY (Country, Language),
|
||||||
|
INDEX (Percentage)
|
||||||
|
);
|
||||||
|
DROP INDEX Country ON City;
|
||||||
|
CREATE INDEX CountryName ON City(Country,Name);
|
||||||
|
CREATE INDEX Name ON City(Name);
|
||||||
|
select * from City
|
||||||
|
where
|
||||||
|
Country='FIN' AND Name IN ('Lahti','Imatra') OR
|
||||||
|
Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
|
||||||
|
Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
|
||||||
|
Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
|
||||||
|
Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
|
||||||
|
Country='PRT' AND Name IN ('Braga', 'Porto') OR
|
||||||
|
Country='FRA' AND Name IN ('Paris', 'Marcel') OR
|
||||||
|
Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
|
||||||
|
Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
|
||||||
|
Country='ITA' AND Name IN ('Napoli', 'Venezia');
|
||||||
|
ID Name Country Population
|
||||||
|
175 Antwerpen BEL 446525
|
||||||
|
176 Gent BEL 224180
|
||||||
|
3068 Berlin DEU 3386667
|
||||||
|
3087 Bonn DEU 301048
|
||||||
|
3242 Lahti FIN 96921
|
||||||
|
2974 Paris FRA 2125246
|
||||||
|
1466 Napoli ITA 1002619
|
||||||
|
1474 Venezia ITA 277305
|
||||||
|
2808 Bergen NOR 230948
|
||||||
|
2807 Oslo NOR 508726
|
||||||
|
2928 Warszawa POL 1615369
|
||||||
|
2931 Wroclaw POL 636765
|
||||||
|
2918 Braga PRT 90535
|
||||||
|
2915 Porto PRT 273060
|
||||||
|
3580 Moscow RUS 8389200
|
||||||
|
3581 St Petersburg RUS 4694000
|
||||||
|
3048 Stockholm SWE 750348
|
||||||
|
3051 Uppsala SWE 189569
|
||||||
|
explain select * from City
|
||||||
|
where
|
||||||
|
Country='FIN' AND Name IN ('Lahti','Imatra') OR
|
||||||
|
Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
|
||||||
|
Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
|
||||||
|
Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
|
||||||
|
Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
|
||||||
|
Country='PRT' AND Name IN ('Braga', 'Porto') OR
|
||||||
|
Country='FRA' AND Name IN ('Paris', 'Marcel') OR
|
||||||
|
Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
|
||||||
|
Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
|
||||||
|
Country='ITA' AND Name IN ('Napoli', 'Venezia');
|
||||||
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
|
1 SIMPLE City range CountryName,Name CountryName 38 NULL 20 Using index condition; Using where
|
||||||
|
DROP DATABASE world;
|
||||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||||
|
@ -1241,6 +1241,59 @@ WHERE ( state = 'Alabama' OR state >= 'Colorado' ) AND id != 9
|
|||||||
|
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # mdev-11574: do not build index merge of two indexes when
|
||||||
|
--echo # one index is an infix of the other index
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
set names utf8;
|
||||||
|
|
||||||
|
CREATE DATABASE world;
|
||||||
|
|
||||||
|
use world;
|
||||||
|
|
||||||
|
--source include/world_schema.inc
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--disable_warnings
|
||||||
|
--source include/world.inc
|
||||||
|
--enable_warnings
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
DROP INDEX Country ON City;
|
||||||
|
CREATE INDEX CountryName ON City(Country,Name);
|
||||||
|
CREATE INDEX Name ON City(Name);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
--disable_result_log
|
||||||
|
--disable_warnings
|
||||||
|
ANALYZE TABLE City;
|
||||||
|
--enable_warnings
|
||||||
|
--enable_result_log
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
let $q=
|
||||||
|
select * from City
|
||||||
|
where
|
||||||
|
Country='FIN' AND Name IN ('Lahti','Imatra') OR
|
||||||
|
Country='RUS' AND Name IN ('St Petersburg', 'Moscow') OR
|
||||||
|
Country='SWE' AND Name IN ('Stockholm', 'Uppsala') OR
|
||||||
|
Country='DEU' AND Name IN ('Berlin', 'Bonn') OR
|
||||||
|
Country='BEL' AND Name IN ('Antwerpen', 'Gent') OR
|
||||||
|
Country='PRT' AND Name IN ('Braga', 'Porto') OR
|
||||||
|
Country='FRA' AND Name IN ('Paris', 'Marcel') OR
|
||||||
|
Country='POL' AND Name IN ('Warszawa', 'Wroclaw') OR
|
||||||
|
Country='NOR' AND Name IN ('Oslo', 'Bergen') OR
|
||||||
|
Country='ITA' AND Name IN ('Napoli', 'Venezia');
|
||||||
|
|
||||||
|
eval $q;
|
||||||
|
eval explain $q;
|
||||||
|
|
||||||
|
|
||||||
|
DROP DATABASE world;
|
||||||
|
|
||||||
#the following command must be the last one in the file
|
#the following command must be the last one in the file
|
||||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||||
|
|
||||||
|
@ -8990,6 +8990,34 @@ bool sel_trees_can_be_ored(RANGE_OPT_PARAM* param,
|
|||||||
DBUG_RETURN(!common_keys->is_clear_all());
|
DBUG_RETURN(!common_keys->is_clear_all());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Check whether the key parts inf_init..inf_end-1 of one index can compose
|
||||||
|
an infix for the key parts key_init..key_end-1 of another index
|
||||||
|
*/
|
||||||
|
|
||||||
|
static
|
||||||
|
bool is_key_infix(KEY_PART *key_init, KEY_PART *key_end,
|
||||||
|
KEY_PART *inf_init, KEY_PART *inf_end)
|
||||||
|
{
|
||||||
|
KEY_PART *key_part, *inf_part;
|
||||||
|
for (key_part= key_init; key_part < key_end; key_part++)
|
||||||
|
{
|
||||||
|
if (key_part->field->eq(inf_init->field))
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (key_part == key_end)
|
||||||
|
return false;
|
||||||
|
for (key_part++, inf_part= inf_init + 1;
|
||||||
|
key_part < key_end && inf_part < inf_end;
|
||||||
|
key_part++, inf_part++)
|
||||||
|
{
|
||||||
|
if (!key_part->field->eq(inf_part->field))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return inf_part == inf_end;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Check whether range parts of two trees must be ored for some indexes
|
Check whether range parts of two trees must be ored for some indexes
|
||||||
|
|
||||||
@ -9046,14 +9074,9 @@ bool sel_trees_must_be_ored(RANGE_OPT_PARAM* param,
|
|||||||
|
|
||||||
KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part;
|
KEY_PART *key2_init= param->key[idx2]+tree2->keys[idx2]->part;
|
||||||
KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no;
|
KEY_PART *key2_end= param->key[idx2]+tree2->keys[idx2]->max_part_no;
|
||||||
KEY_PART *part1, *part2;
|
if (!is_key_infix(key1_init, key1_end, key2_init, key2_end) &&
|
||||||
for (part1= key1_init, part2= key2_init;
|
!is_key_infix(key2_init, key2_end, key1_init, key1_end))
|
||||||
part1 < key1_end && part2 < key2_end;
|
DBUG_RETURN(FALSE);
|
||||||
part1++, part2++)
|
|
||||||
{
|
|
||||||
if (!part1->field->eq(part2->field))
|
|
||||||
DBUG_RETURN(FALSE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user