mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
Merge
This commit is contained in:
commit
c4080280df
33 changed files with 4032 additions and 488 deletions
|
@ -31,6 +31,7 @@ extern "C" {
|
|||
#define tree_set_pointer(element,ptr) *((uchar **) (element+1))=((uchar*) (ptr))
|
||||
|
||||
#define TREE_NO_DUPS 1
|
||||
#define TREE_ONLY_DUPS 2
|
||||
|
||||
typedef enum { left_root_right, right_root_left } TREE_WALK;
|
||||
typedef uint32 element_count;
|
||||
|
|
|
@ -539,7 +539,7 @@ INSERT INTO t1 SELECT * FROM t1;
|
|||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
SET SESSION sort_buffer_size=1;
|
||||
SET SESSION sort_buffer_size=1024*8;
|
||||
EXPLAIN
|
||||
SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%'
|
||||
ORDER BY a,b;
|
||||
|
|
1052
mysql-test/r/index_intersect.result
Normal file
1052
mysql-test/r/index_intersect.result
Normal file
File diff suppressed because it is too large
Load diff
1051
mysql-test/r/index_intersect_innodb.result
Normal file
1051
mysql-test/r/index_intersect_innodb.result
Normal file
File diff suppressed because it is too large
Load diff
|
@ -1,3 +1,5 @@
|
|||
set @optimizer_switch_save= @@optimizer_switch;
|
||||
set optimizer_switch='index_merge_sort_intersection=off';
|
||||
#---------------- Index merge test 2 -------------------------------------------
|
||||
SET SESSION STORAGE_ENGINE = InnoDB;
|
||||
drop table if exists t1,t2;
|
||||
|
@ -709,3 +711,4 @@ WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
|||
COUNT(*)
|
||||
6145
|
||||
DROP TABLE t1;
|
||||
set optimizer_switch= @optimizer_switch_save;
|
||||
|
|
|
@ -1,3 +1,5 @@
|
|||
set @optimizer_switch_save= @@optimizer_switch;
|
||||
set optimizer_switch='index_merge_sort_intersection=off';
|
||||
#---------------- Index merge test 1 -------------------------------------------
|
||||
SET SESSION STORAGE_ENGINE = MyISAM;
|
||||
drop table if exists t0, t1, t2, t3, t4;
|
||||
|
@ -205,10 +207,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 2 Using sort_union(i1_3,i2_3); Using where
|
||||
explain select key3 from t2 where key1 <100 or key2 < 100;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 index i1_3,i2_3 i321 12 NULL 1024 Using where; Using index
|
||||
1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where
|
||||
explain select key7 from t2 where key1 <100 or key2 < 100;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t2 ALL i1_3,i2_3 NULL NULL NULL 1024 Using where
|
||||
1 SIMPLE t2 index_merge i1_3,i2_3 i1_3,i2_3 4,4 NULL 188 Using sort_union(i1_3,i2_3); Using where
|
||||
create table t4 (
|
||||
key1a int not null,
|
||||
key1b int not null,
|
||||
|
@ -569,9 +571,7 @@ INSERT INTO t1 SELECT * FROM t1;
|
|||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
INSERT INTO t1 SELECT * FROM t1;
|
||||
SET SESSION sort_buffer_size=1;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '1'
|
||||
SET SESSION sort_buffer_size=1024*8;
|
||||
EXPLAIN
|
||||
SELECT * FROM t1 FORCE INDEX(a,b) WHERE a LIKE 'a%' OR b LIKE 'b%'
|
||||
ORDER BY a,b;
|
||||
|
@ -1494,19 +1494,19 @@ DROP TABLE t1,t2;
|
|||
#
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off
|
||||
set optimizer_switch='index_merge=off,index_merge_union=off';
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off
|
||||
set optimizer_switch='index_merge_union=on';
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=off,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=off
|
||||
set optimizer_switch='default,index_merge_sort_union=off';
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=off,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
set optimizer_switch=4;
|
||||
ERROR 42000: Variable 'optimizer_switch' can't be set to the value of '4'
|
||||
set optimizer_switch=NULL;
|
||||
|
@ -1533,21 +1533,21 @@ set optimizer_switch=default;
|
|||
set optimizer_switch='index_merge=off,index_merge_union=off,default';
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=off,index_merge_union=off,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
set optimizer_switch=default;
|
||||
select @@global.optimizer_switch;
|
||||
@@global.optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
set @@global.optimizer_switch=default;
|
||||
select @@global.optimizer_switch;
|
||||
@@global.optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
#
|
||||
# Check index_merge's @@optimizer_switch flags
|
||||
#
|
||||
select @@optimizer_switch;
|
||||
@@optimizer_switch
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
create table t0 (a int);
|
||||
insert into t0 values (0),(1),(2),(3),(4),(5),(6),(7),(8),(9);
|
||||
create table t1 (a int, b int, c int, filler char(100),
|
||||
|
@ -1624,7 +1624,7 @@ explain select * from t1 where a=10 and b=10;
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
||||
No intersect if it is disabled:
|
||||
set optimizer_switch='default,index_merge_intersection=off';
|
||||
set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off';
|
||||
explain select * from t1 where a=10 and b=10;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE t1 ref a,b a 5 const 49 Using where
|
||||
|
@ -1657,5 +1657,6 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
set optimizer_switch=default;
|
||||
show variables like 'optimizer_switch';
|
||||
Variable_name Value
|
||||
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on
|
||||
optimizer_switch index_merge=on,index_merge_union=on,index_merge_sort_union=on,index_merge_intersection=on,index_merge_sort_intersection=on
|
||||
drop table t0, t1;
|
||||
set optimizer_switch= @optimizer_switch_save;
|
||||
|
|
|
@ -1421,9 +1421,9 @@ DROP TABLE t1;
|
|||
#
|
||||
create table t1(a int, b tinytext);
|
||||
insert into t1 values (1,2),(3,2);
|
||||
set session sort_buffer_size= 30000;
|
||||
set session sort_buffer_size= 1000;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '30000'
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '1000'
|
||||
set session max_sort_length= 2180;
|
||||
select * from t1 order by b;
|
||||
ERROR HY001: Out of sort memory; increase server sort buffer size
|
||||
|
|
|
@ -38,6 +38,7 @@ SELECT COUNT(*) FROM CountryLanguage;
|
|||
COUNT(*)
|
||||
984
|
||||
CREATE INDEX Name ON City(Name);
|
||||
set session optimizer_switch='index_merge_sort_intersection=off';
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000);
|
||||
|
@ -71,9 +72,9 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City range Population Population 4 NULL 459 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE (Population > 101000 AND Population < 103000);
|
||||
WHERE (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population Population 4 NULL 81 Using where
|
||||
1 SIMPLE City range Population Population 4 NULL 39 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
|
||||
|
@ -88,9 +89,9 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population,Country,Name Population 4 NULL 81 Using where
|
||||
1 SIMPLE City range Population,Country,Name Population 4 NULL 39 Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 115000);
|
||||
|
@ -153,24 +154,20 @@ ID Name Country Population
|
|||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
ID Name Country Population
|
||||
637 Mit Ghamr EGY 101801
|
||||
707 Marbella ESP 101144
|
||||
3411 Ceyhan TUR 102412
|
||||
3792 Tartu EST 101246
|
||||
4027 Cape Coral USA 102286
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
ID Name Country Population
|
||||
707 Marbella ESP 101144
|
||||
3792 Tartu EST 101246
|
||||
4032 Cambridge USA 101355
|
||||
637 Mit Ghamr EGY 101801
|
||||
4027 Cape Coral USA 102286
|
||||
3411 Ceyhan TUR 102412
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (Name < 'Ac');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -328,9 +325,9 @@ ID Name Country Population
|
|||
1003 Pemalang IDN 103500
|
||||
2663 Río Bravo MEX 103901
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110);
|
||||
SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range PRIMARY PRIMARY 4 NULL 61 Using where
|
||||
1 SIMPLE City range PRIMARY PRIMARY 4 NULL 81 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -353,11 +350,11 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City range Name Name 35 NULL 72 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' 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 61 Using where
|
||||
1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 41 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
|
@ -373,7 +370,7 @@ OR ((ID BETWEEN 300 AND 600) AND
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 128 Using sort_union(Name,Country,Population); Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
ID Name Country Population
|
||||
|
@ -384,13 +381,10 @@ ID Name Country Population
|
|||
7 Haag NLD 440900
|
||||
16 Haarlem NLD 148772
|
||||
25 Haarlemmermeer NLD 110722
|
||||
31 Heerlen NLD 95052
|
||||
33 Willemstad ANT 2345
|
||||
34 Tirana ALB 270000
|
||||
100 Paraná ARG 207041
|
||||
102 Posadas ARG 201273
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
ID Name Country Population
|
||||
|
@ -401,9 +395,6 @@ ID Name Country Population
|
|||
7 Haag NLD 440900
|
||||
16 Haarlem NLD 148772
|
||||
25 Haarlemmermeer NLD 110722
|
||||
31 Heerlen NLD 95052
|
||||
33 Willemstad ANT 2345
|
||||
34 Tirana ALB 270000
|
||||
100 Paraná ARG 207041
|
||||
102 Posadas ARG 201273
|
||||
SELECT * FROM City USE INDEX()
|
||||
|
@ -726,119 +717,55 @@ SELECT * FROM City WHERE Name LIKE 'P%';
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Name Name 35 NULL 135 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population Population 4 NULL 81 Using where
|
||||
1 SIMPLE City range Population Population 4 NULL 39 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Country='USA';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref Country,CountryPopulation Country 3 const 267 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 15 Using sort_union(CountryPopulation,Name); Using where
|
||||
1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 8 Using sort_union(CountryPopulation,Name); Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' )
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 267 Using where
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
ID Name Country Population
|
||||
3943 Pasadena USA 141674
|
||||
3953 Pasadena USA 133936
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
ID Name Country Population
|
||||
3943 Pasadena USA 141674
|
||||
3953 Pasadena USA 133936
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
3797 Philadelphia USA 1517550
|
||||
3798 Phoenix USA 1321045
|
||||
3820 Portland USA 529121
|
||||
3844 Pittsburgh USA 334563
|
||||
3870 Plano USA 222030
|
||||
3912 Providence USA 173618
|
||||
3930 Pomona USA 149473
|
||||
3932 Paterson USA 149222
|
||||
3943 Pasadena USA 141674
|
||||
3951 Pembroke Pines USA 137427
|
||||
3953 Pasadena USA 133936
|
||||
3967 Paradise USA 124682
|
||||
3986 Palmdale USA 116670
|
||||
3996 Peoria USA 112936
|
||||
4007 Peoria USA 108364
|
||||
4016 Provo USA 105166
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
4035 Portsmouth USA 100565
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
3797 Philadelphia USA 1517550
|
||||
3798 Phoenix USA 1321045
|
||||
3820 Portland USA 529121
|
||||
3844 Pittsburgh USA 334563
|
||||
3870 Plano USA 222030
|
||||
3912 Providence USA 173618
|
||||
3930 Pomona USA 149473
|
||||
3932 Paterson USA 149222
|
||||
3943 Pasadena USA 141674
|
||||
3951 Pembroke Pines USA 137427
|
||||
3953 Pasadena USA 133936
|
||||
3967 Paradise USA 124682
|
||||
3986 Palmdale USA 116670
|
||||
3996 Peoria USA 112936
|
||||
4007 Peoria USA 108364
|
||||
4016 Provo USA 105166
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
4035 Portsmouth USA 100565
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
CREATE INDEX CountryName ON City(Country,Name);
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Country='USA';
|
||||
|
@ -900,9 +827,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 11 Using sort_union(CountryName,PRIMARY); Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 110000) OR
|
||||
ID BETWEEN 3500 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 267 Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
|
@ -938,21 +866,21 @@ ID Name Country Population
|
|||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 and Population < 102000) OR
|
||||
|
@ -1460,3 +1388,4 @@ f1 f2 f3 f4
|
|||
9 0 2 6
|
||||
SET SESSION optimizer_switch=DEFAULT;
|
||||
DROP TABLE t1;
|
||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||
|
|
|
@ -39,6 +39,7 @@ SELECT COUNT(*) FROM CountryLanguage;
|
|||
COUNT(*)
|
||||
984
|
||||
CREATE INDEX Name ON City(Name);
|
||||
set session optimizer_switch='index_merge_sort_intersection=off';
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE (Population >= 100000 OR Name LIKE 'P%' OR Population < 100000);
|
||||
|
@ -72,9 +73,9 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City range Population Population 4 NULL 458 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE (Population > 101000 AND Population < 103000);
|
||||
WHERE (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population Population 4 NULL 80 Using where
|
||||
1 SIMPLE City range Population Population 4 NULL 38 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'));
|
||||
|
@ -89,9 +90,9 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population,Country,Name Population 4 NULL 80 Using where
|
||||
1 SIMPLE City range Population,Country,Name Population 4 NULL 38 Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 115000);
|
||||
|
@ -154,24 +155,20 @@ ID Name Country Population
|
|||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
ID Name Country Population
|
||||
637 Mit Ghamr EGY 101801
|
||||
707 Marbella ESP 101144
|
||||
3411 Ceyhan TUR 102412
|
||||
3792 Tartu EST 101246
|
||||
4027 Cape Coral USA 102286
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
ID Name Country Population
|
||||
707 Marbella ESP 101144
|
||||
3792 Tartu EST 101246
|
||||
4032 Cambridge USA 101355
|
||||
637 Mit Ghamr EGY 101801
|
||||
4027 Cape Coral USA 102286
|
||||
3411 Ceyhan TUR 102412
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (Name < 'Ac');
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -329,9 +326,9 @@ ID Name Country Population
|
|||
1003 Pemalang IDN 103500
|
||||
2663 Río Bravo MEX 103901
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110);
|
||||
SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range PRIMARY PRIMARY 4 NULL 60 Using where
|
||||
1 SIMPLE City range PRIMARY PRIMARY 4 NULL 79 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -354,11 +351,11 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City range Name Name 35 NULL 133 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' 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 60 Using where
|
||||
1 SIMPLE City range PRIMARY,Population,Country,Name PRIMARY 4 NULL 40 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 800) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
|
@ -372,9 +369,9 @@ WHERE ((ID < 600) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
|
|||
OR ((ID BETWEEN 300 AND 600) 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 1242 Using where
|
||||
1 SIMPLE City index_merge PRIMARY,Population,Country,Name Name,Country,Population 35,3,4 NULL 188 Using sort_union(Name,Country,Population); Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
ID Name Country Population
|
||||
|
@ -385,13 +382,10 @@ ID Name Country Population
|
|||
7 Haag NLD 440900
|
||||
16 Haarlem NLD 148772
|
||||
25 Haarlemmermeer NLD 110722
|
||||
31 Heerlen NLD 95052
|
||||
33 Willemstad ANT 2345
|
||||
34 Tirana ALB 270000
|
||||
100 Paraná ARG 207041
|
||||
102 Posadas ARG 201273
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
ID Name Country Population
|
||||
|
@ -402,9 +396,6 @@ ID Name Country Population
|
|||
7 Haag NLD 440900
|
||||
16 Haarlem NLD 148772
|
||||
25 Haarlemmermeer NLD 110722
|
||||
31 Heerlen NLD 95052
|
||||
33 Willemstad ANT 2345
|
||||
34 Tirana ALB 270000
|
||||
100 Paraná ARG 207041
|
||||
102 Posadas ARG 201273
|
||||
SELECT * FROM City USE INDEX()
|
||||
|
@ -577,6 +568,20 @@ WHERE ((ID < 200) AND (Name LIKE 'Ha%' OR (Country > 'A' AND Country < 'ARG')))
|
|||
OR ((ID BETWEEN 300 AND 600) AND
|
||||
(Name LIKE 'Pa%' OR (Population > 103000 AND Population < 104000)));
|
||||
ID Name Country Population
|
||||
339 Passo Fundo BRA 166343
|
||||
364 Parnaíba BRA 129756
|
||||
372 Paranaguá BRA 126076
|
||||
379 Palmas BRA 121919
|
||||
386 Patos de Minas BRA 119262
|
||||
411 Guaratinguetá BRA 103433
|
||||
412 Cachoeirinha BRA 103240
|
||||
413 Codó BRA 103153
|
||||
424 Passos BRA 98570
|
||||
430 Paulo Afonso BRA 97291
|
||||
435 Parnamirim BRA 96210
|
||||
448 Patos BRA 90519
|
||||
451 Palhoça BRA 89465
|
||||
517 Oldham GBR 103931
|
||||
1 Kabul AFG 1780000
|
||||
2 Qandahar AFG 237500
|
||||
3 Herat AFG 186800
|
||||
|
@ -601,20 +606,6 @@ ID Name Country Population
|
|||
68 Ajman ARE 114395
|
||||
129 Oranjestad ABW 29034
|
||||
191 Hamilton BMU 1200
|
||||
339 Passo Fundo BRA 166343
|
||||
364 Parnaíba BRA 129756
|
||||
372 Paranaguá BRA 126076
|
||||
379 Palmas BRA 121919
|
||||
386 Patos de Minas BRA 119262
|
||||
411 Guaratinguetá BRA 103433
|
||||
412 Cachoeirinha BRA 103240
|
||||
413 Codó BRA 103153
|
||||
424 Passos BRA 98570
|
||||
430 Paulo Afonso BRA 97291
|
||||
435 Parnamirim BRA 96210
|
||||
448 Patos BRA 90519
|
||||
451 Palhoça BRA 89465
|
||||
517 Oldham GBR 103931
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Population > 101000 AND Population < 102000;
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
|
@ -727,119 +718,55 @@ SELECT * FROM City WHERE Name LIKE 'P%';
|
|||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Name Name 35 NULL 235 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City range Population Population 4 NULL 80 Using where
|
||||
1 SIMPLE City range Population Population 4 NULL 38 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Country='USA';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref Country,CountryPopulation Country 3 const 274 Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 17 Using sort_union(CountryPopulation,Name); Using where
|
||||
1 SIMPLE City index_merge Population,Country,Name,CountryPopulation CountryPopulation,Name 7,35 NULL 10 Using sort_union(CountryPopulation,Name); Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' )
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref Population,Country,Name,CountryPopulation Country 3 const 274 Using where
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
ID Name Country Population
|
||||
3943 Pasadena USA 141674
|
||||
3953 Pasadena USA 133936
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
ID Name Country Population
|
||||
3943 Pasadena USA 141674
|
||||
3953 Pasadena USA 133936
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
3797 Philadelphia USA 1517550
|
||||
3798 Phoenix USA 1321045
|
||||
3820 Portland USA 529121
|
||||
3844 Pittsburgh USA 334563
|
||||
3870 Plano USA 222030
|
||||
3912 Providence USA 173618
|
||||
3930 Pomona USA 149473
|
||||
3932 Paterson USA 149222
|
||||
3943 Pasadena USA 141674
|
||||
3951 Pembroke Pines USA 137427
|
||||
3953 Pasadena USA 133936
|
||||
3967 Paradise USA 124682
|
||||
3986 Palmdale USA 116670
|
||||
3996 Peoria USA 112936
|
||||
4007 Peoria USA 108364
|
||||
4016 Provo USA 105166
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
4035 Portsmouth USA 100565
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
3797 Philadelphia USA 1517550
|
||||
3798 Phoenix USA 1321045
|
||||
3820 Portland USA 529121
|
||||
3844 Pittsburgh USA 334563
|
||||
3870 Plano USA 222030
|
||||
3912 Providence USA 173618
|
||||
3930 Pomona USA 149473
|
||||
3932 Paterson USA 149222
|
||||
3943 Pasadena USA 141674
|
||||
3951 Pembroke Pines USA 137427
|
||||
3953 Pasadena USA 133936
|
||||
3967 Paradise USA 124682
|
||||
3986 Palmdale USA 116670
|
||||
3996 Peoria USA 112936
|
||||
4007 Peoria USA 108364
|
||||
4016 Provo USA 105166
|
||||
4023 Gary USA 102746
|
||||
4024 Berkeley USA 102743
|
||||
4025 Santa Clara USA 102361
|
||||
4026 Green Bay USA 102313
|
||||
4027 Cape Coral USA 102286
|
||||
4028 Arvada USA 102153
|
||||
4029 Pueblo USA 102121
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
4035 Portsmouth USA 100565
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
CREATE INDEX CountryName ON City(Country,Name);
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Country='USA';
|
||||
|
@ -901,9 +828,10 @@ id select_type table type possible_keys key key_len ref rows Extra
|
|||
1 SIMPLE City index_merge PRIMARY,Population,Country,Name,CountryPopulation,CountryName CountryName,PRIMARY 38,4 NULL 10 Using sort_union(CountryName,PRIMARY); Using where
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 110000) OR
|
||||
ID BETWEEN 3500 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
id select_type table type possible_keys key key_len ref rows Extra
|
||||
1 SIMPLE City ref PRIMARY,Population,Country,Name,CountryPopulation,CountryName Country 3 const 274 Using where
|
||||
SELECT * FROM City USE INDEX ()
|
||||
|
@ -939,21 +867,21 @@ ID Name Country Population
|
|||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
ID Name Country Population
|
||||
4030 Sandy USA 101853
|
||||
4031 Athens-Clarke County USA 101489
|
||||
4032 Cambridge USA 101355
|
||||
3880 Shreveport USA 200145
|
||||
3946 Bridgeport USA 139529
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 and Population < 102000) OR
|
||||
|
@ -1461,4 +1389,5 @@ f1 f2 f3 f4
|
|||
9 0 2 6
|
||||
SET SESSION optimizer_switch=DEFAULT;
|
||||
DROP TABLE t1;
|
||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
||||
|
|
|
@ -3667,8 +3667,6 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
|
|||
CREATE TABLE t2 (x int auto_increment, y int, z int,
|
||||
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
|
||||
SET SESSION sort_buffer_size = 32 * 1024;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
|
||||
SELECT SQL_NO_CACHE COUNT(*)
|
||||
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
|
||||
FROM t1) t;
|
||||
|
@ -4104,8 +4102,6 @@ INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
|
|||
INSERT INTO `t2` VALUES ('abcdefghijk');
|
||||
INSERT INTO `t2` VALUES ('asdf');
|
||||
SET session sort_buffer_size=8192;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
|
||||
SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
|
||||
d1
|
||||
1
|
||||
|
|
|
@ -971,6 +971,7 @@ tmpdir #
|
|||
select * from information_schema.session_variables where variable_name like 'tmpdir';
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
TMPDIR #
|
||||
set sort_buffer_size=1024*8;
|
||||
select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
|
||||
@@ssl_ca @@ssl_capath @@ssl_cert @@ssl_cipher @@ssl_key
|
||||
# # # # #
|
||||
|
|
|
@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
|
|||
UPDATE t2 SET c='2007-01-03';
|
||||
INSERT INTO t1(b,c) SELECT b,c FROM t2;
|
||||
set @@sort_buffer_size=8192;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
3072
|
||||
|
|
|
@ -679,8 +679,6 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
|
|||
UPDATE t2 SET c='2007-01-03';
|
||||
INSERT INTO t1(b,c) SELECT b,c FROM t2;
|
||||
set @@sort_buffer_size=8192;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
|
||||
SELECT COUNT(*) FROM t1;
|
||||
COUNT(*)
|
||||
3072
|
||||
|
|
|
@ -3667,8 +3667,6 @@ CREATE TABLE t1 (a int, b int auto_increment, PRIMARY KEY (b));
|
|||
CREATE TABLE t2 (x int auto_increment, y int, z int,
|
||||
PRIMARY KEY (x), FOREIGN KEY (y) REFERENCES t1 (b));
|
||||
SET SESSION sort_buffer_size = 32 * 1024;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '32768'
|
||||
SELECT SQL_NO_CACHE COUNT(*)
|
||||
FROM (SELECT a, b, (SELECT x FROM t2 WHERE y=b ORDER BY z DESC LIMIT 1) c
|
||||
FROM t1) t;
|
||||
|
@ -4104,8 +4102,6 @@ INSERT INTO `t1` VALUES ('asdf','2007-02-08 01:11:26');
|
|||
INSERT INTO `t2` VALUES ('abcdefghijk');
|
||||
INSERT INTO `t2` VALUES ('asdf');
|
||||
SET session sort_buffer_size=8192;
|
||||
Warnings:
|
||||
Warning 1292 Truncated incorrect sort_buffer_size value: '8192'
|
||||
SELECT (SELECT 1 FROM t1 WHERE t1.a=t2.a ORDER BY t1.b LIMIT 1) AS d1 FROM t2;
|
||||
d1
|
||||
1
|
||||
|
|
419
mysql-test/t/index_intersect.test
Normal file
419
mysql-test/t/index_intersect.test
Normal file
|
@ -0,0 +1,419 @@
|
|||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1,t2,t3,t4;
|
||||
DROP DATABASE IF EXISTS world;
|
||||
--enable_warnings
|
||||
|
||||
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
|
||||
|
||||
SELECT COUNT(*) FROM Country;
|
||||
SELECT COUNT(*) FROM City;
|
||||
SELECT COUNT(*) FROM CountryLanguage;
|
||||
|
||||
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
|
||||
|
||||
|
||||
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
|
||||
|
||||
SELECT COUNT(*) FROM City;
|
||||
|
||||
# The output of the next 6 queries tells us about selectivities
|
||||
# of the conditions utilized in 4 queries following after them
|
||||
|
||||
SELECT COUNT(*) FROM City WHERE Name LIKE 'C%';
|
||||
SELECT COUNT(*) FROM City WHERE Name LIKE 'M%';
|
||||
SELECT COUNT(*) FROM City WHERE Population > 1000000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 1500000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 300000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 5000000;
|
||||
|
||||
# The pattern of the WHERE condition used in the following 4 queries is
|
||||
# range(key1) AND range(key2)
|
||||
# Varying values of the constants in the conjuncts of the condition
|
||||
# we can get either an index intersection retrieval over key1 and key2
|
||||
# or a range index scan for one of these indexes
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'C%' AND Population > 1000000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'M%' AND Population > 1500000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'M%' AND Population > 300000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'M%' AND Population > 5000000;
|
||||
|
||||
|
||||
# The following 8 queries check that
|
||||
# the previous 4 plans are valid and return
|
||||
# the correct results when executed
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name LIKE 'C%' AND Population > 1000000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'C%' AND Population > 1000000;
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name LIKE 'M%' AND Population > 1500000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'M%' AND Population > 1500000;
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name LIKE 'M%' AND Population > 300000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'M%' AND Population > 300000;
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name LIKE 'M%' AND Population > 5000000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name LIKE 'M%' AND Population > 5000000;
|
||||
|
||||
|
||||
# The output of the next 6 queries tells us about selectivities
|
||||
# of the conditions utilized in 3 queries following after them
|
||||
|
||||
SELECT COUNT(*) FROM City WHERE Name BETWEEN 'M' AND 'N';
|
||||
SELECT COUNT(*) FROM City WHERE Name BETWEEN 'G' AND 'J';
|
||||
SELECT COUNT(*) FROM City WHERE Population > 1000000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 500000;
|
||||
SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
|
||||
SELECT COUNT(*) FROM City WHERE Country LIKE 'B%';
|
||||
|
||||
|
||||
# The pattern of the WHERE condition used in the following 3 queries is
|
||||
# range(key1) AND range(key2) AND range(key3)
|
||||
# Varying values of the constants in the conjuncts of the condition
|
||||
# we can get index intersection over different pairs of keys:
|
||||
# over(key1,key2), over(key1,key3) and over(key2,key3)
|
||||
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
# The following 6 queries check that
|
||||
# the previous 3 plans are valid and return
|
||||
# the correct results when executed
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'M' AND 'N' AND Population > 1000000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
# The output of the next 12 queries tells us about selectivities
|
||||
# of the conditions utilized in 5 queries following after them
|
||||
|
||||
SELECT COUNT(*) FROM City WHERE ID BETWEEN 501 AND 1000;
|
||||
SELECT COUNT(*) FROM City WHERE ID BETWEEN 1 AND 500;
|
||||
SELECT COUNT(*) FROM City WHERE ID BETWEEN 2001 AND 2500;
|
||||
SELECT COUNT(*) FROM City WHERE ID BETWEEN 3701 AND 4000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 700000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 1000000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 300000;
|
||||
SELECT COUNT(*) FROM City WHERE Population > 600000;
|
||||
SELECT COUNT(*) FROM City WHERE Country LIKE 'C%';
|
||||
SELECT COUNT(*) FROM City WHERE Country LIKE 'A%';
|
||||
SELECT COUNT(*) FROM City WHERE Country LIKE 'L%';
|
||||
SELECT COUNT(*) FROM City WHERE Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
|
||||
# The pattern of the WHERE condition used in the following 5 queries is
|
||||
# range(key1) AND range(key2) AND range(key3)
|
||||
# with key1 happens to be a primary key (it matters only for InnoDB)
|
||||
# Varying values of the constants in the conjuncts of the condition
|
||||
# we can get index intersection either over all three keys, or over
|
||||
# different pairs, or a range scan over one of these keys.
|
||||
# Bear in mind that the condition (Country LIKE 'A%') is actually
|
||||
# equivalent to the condition (Country BETWEEN 'A' AND 'B') for the
|
||||
# tested instance the table City.
|
||||
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000
|
||||
AND Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
|
||||
AND Country BETWEEN 'S' AND 'Z' ;
|
||||
|
||||
|
||||
# The following 10 queries check that
|
||||
# the previous 5 plans are valid and return
|
||||
# the correct results when executed
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'L%';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
|
||||
AND Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3701 AND 4000 AND Population > 700000
|
||||
AND Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
|
||||
AND Country BETWEEN 'S' AND 'Z' ;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
|
||||
AND Country BETWEEN 'S' AND 'Z' ;
|
||||
|
||||
|
||||
SET SESSION sort_buffer_size = 2048;
|
||||
|
||||
|
||||
# The following EXPLAIN command demonstrate that the execution plans
|
||||
# may be different if sort_buffer_size is set to a small value
|
||||
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'C%' AND Population > 1000000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'M%' AND Population > 1500000;
|
||||
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 1000000 AND Country LIKE 'B%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
|
||||
AND Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
|
||||
#Yet the query themselves return the correct results in this case as well
|
||||
|
||||
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'C%' AND Population > 1000000;
|
||||
|
||||
SELECT * FROM City WHERE
|
||||
Name LIKE 'M%' AND Population > 1500000;
|
||||
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 700000 AND Country LIKE 'B%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Name BETWEEN 'G' AND 'J' AND Population > 500000 AND Country LIKE 'C%';
|
||||
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 1 AND 500 AND Population > 1000000 AND Country LIKE 'A%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000
|
||||
AND Country BETWEEN 'S' AND 'Z';
|
||||
|
||||
|
||||
SET SESSION sort_buffer_size = default;
|
||||
|
||||
# Instead of the index on the column Country create two compound indexes
|
||||
# including this column as the first component
|
||||
|
||||
DROP INDEX Country ON City;
|
||||
|
||||
CREATE INDEX CountryID ON City(Country,ID);
|
||||
CREATE INDEX CountryName ON City(Country,Name);
|
||||
|
||||
--disable_query_log
|
||||
--disable_result_log
|
||||
--disable_warnings
|
||||
ANALYZE TABLE City;
|
||||
--enable_warnings
|
||||
--enable_result_log
|
||||
--enable_query_log
|
||||
|
||||
# Check that the first component of a compound index can be used for
|
||||
# index intersection, even in the cases when we have a ref access
|
||||
# for this component
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Country LIKE 'M%' AND Population > 1000000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Country='CHN' AND Population > 1500000;
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
|
||||
|
||||
|
||||
# Check that the previous 3 plans return the right results when executed
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Country LIKE 'M%' AND Population > 1000000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Country LIKE 'M%' AND Population > 700000;
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Country='CHN' AND Population > 1500000;
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Country='CHN' AND Population > 1500000;
|
||||
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE Country='CHN' AND Population > 1500000 AND Name LIKE 'C%';
|
||||
|
||||
|
||||
DROP DATABASE world;
|
||||
|
||||
use test;
|
||||
|
||||
#
|
||||
# Bug #684086: crash with EXPLAIN in InnoDB for index intersection
|
||||
# of two indexes one of which is primary
|
||||
#
|
||||
|
||||
CREATE TABLE t1 (
|
||||
f1 int,
|
||||
f4 varchar(32),
|
||||
f5 int,
|
||||
PRIMARY KEY (f1),
|
||||
KEY (f4)
|
||||
) ENGINE=InnoDB;
|
||||
|
||||
INSERT INTO t1 VALUES
|
||||
(5,'H',1), (9,'g',0), (527,'i',0), (528,'y',1), (529,'S',6),
|
||||
(530,'m',7), (531,'b',2), (532,'N',1), (533,'V',NULL), (534,'l',1),
|
||||
(535,'M',0), (536,'w',1), (537,'j',5), (538,'l',0), (539,'n',2),
|
||||
(540,'m',2), (541,'r',2), (542,'l',2), (543,'h',3),(544,'o',0),
|
||||
(956,'h',0), (957,'g',0), (958,'W',5), (959,'s',3), (960,'w',0),
|
||||
(961,'q',0), (962,'e',NULL), (963,'u',7), (964,'q',1), (965,'N',NULL),
|
||||
(966,'e',0), (967,'t',3), (968,'e',6), (969,'f',NULL), (970,'j',0),
|
||||
(971,'s',3), (972,'I',0), (973,'h',4), (974,'g',1), (975,'s',0),
|
||||
(976,'r',3), (977,'x',1), (978,'v',8), (979,'j',NULL), (980,'z',7),
|
||||
(981,'t',9), (982,'j',5), (983,'u',NULL), (984,'g',6), (985,'w',1),
|
||||
(986,'h',1), (987,'v',0), (988,'v',0), (989,'c',2), (990,'b',7),
|
||||
(991,'z',0), (992,'M',1), (993,'u',2), (994,'r',2), (995,'b',4),
|
||||
(996,'A',2), (997,'u',0), (998,'a',0), (999,'j',2), (1,'I',2);
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM t1
|
||||
WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
|
||||
|
||||
SELECT * FROM t1
|
||||
WHERE (f1 < 535 OR f1 > 985) AND ( f4='r' OR f4 LIKE 'a%' ) ;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
SET SESSION optimizer_switch='index_merge_sort_intersection=on';
|
7
mysql-test/t/index_intersect_innodb.test
Normal file
7
mysql-test/t/index_intersect_innodb.test
Normal file
|
@ -0,0 +1,7 @@
|
|||
--source include/have_innodb.inc
|
||||
|
||||
SET SESSION STORAGE_ENGINE='InnoDB';
|
||||
|
||||
--source t/index_intersect.test
|
||||
|
||||
SET SESSION STORAGE_ENGINE=DEFAULT;
|
|
@ -18,6 +18,11 @@ let $engine_type= InnoDB;
|
|||
# InnoDB does not support Merge tables (affects include/index_merge1.inc)
|
||||
let $merge_table_support= 0;
|
||||
|
||||
set @optimizer_switch_save= @@optimizer_switch;
|
||||
|
||||
set optimizer_switch='index_merge_sort_intersection=off';
|
||||
|
||||
|
||||
# The first two tests are disabled because of non deterministic explain output.
|
||||
# If include/index_merge1.inc can be enabled for InnoDB and all other
|
||||
# storage engines, please remove the subtest for Bug#21277 from
|
||||
|
@ -84,3 +89,5 @@ SELECT COUNT(*) FROM
|
|||
WHERE a BETWEEN 2 AND 7 OR pk=1000000) AS t;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
set optimizer_switch= @optimizer_switch_save;
|
||||
|
|
|
@ -14,6 +14,10 @@ let $engine_type= MyISAM;
|
|||
# MyISAM supports Merge tables
|
||||
let $merge_table_support= 1;
|
||||
|
||||
set @optimizer_switch_save= @@optimizer_switch;
|
||||
|
||||
set optimizer_switch='index_merge_sort_intersection=off';
|
||||
|
||||
--source include/index_merge1.inc
|
||||
--source include/index_merge_ror.inc
|
||||
--source include/index_merge2.inc
|
||||
|
@ -164,7 +168,7 @@ set optimizer_switch='default,index_merge=off';
|
|||
explain select * from t1 where a=10 and b=10;
|
||||
|
||||
--echo No intersect if it is disabled:
|
||||
set optimizer_switch='default,index_merge_intersection=off';
|
||||
set optimizer_switch='default,index_merge_sort_intersection=off,index_merge_intersection=off';
|
||||
explain select * from t1 where a=10 and b=10;
|
||||
|
||||
--echo Do intersect when union was disabled
|
||||
|
@ -195,3 +199,5 @@ show variables like 'optimizer_switch';
|
|||
|
||||
drop table t0, t1;
|
||||
|
||||
set optimizer_switch= @optimizer_switch_save;
|
||||
|
||||
|
|
|
@ -843,7 +843,7 @@ DROP TABLE t1;
|
|||
--echo #
|
||||
create table t1(a int, b tinytext);
|
||||
insert into t1 values (1,2),(3,2);
|
||||
set session sort_buffer_size= 30000;
|
||||
set session sort_buffer_size= 1000;
|
||||
set session max_sort_length= 2180;
|
||||
--error 1038
|
||||
select * from t1 order by b;
|
||||
|
|
|
@ -33,6 +33,8 @@ ANALYZE TABLE City;
|
|||
--enable_result_log
|
||||
--enable_query_log
|
||||
|
||||
set session optimizer_switch='index_merge_sort_intersection=off';
|
||||
|
||||
# The following 4 queries are added for code coverage
|
||||
|
||||
#the exptected # of rows differ on 32-bit and 64-bit platforms for innodb
|
||||
|
@ -68,7 +70,7 @@ SELECT * FROM City
|
|||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE (Population > 101000 AND Population < 103000);
|
||||
WHERE (Population > 101000 AND Population < 102000);
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
|
@ -88,7 +90,7 @@ SELECT * FROM City
|
|||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
|
||||
# The following 4 queries check that the plans
|
||||
# for the previous 2 plans are valid
|
||||
|
@ -103,11 +105,11 @@ SELECT * FROM City
|
|||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ((Name > 'Ca' AND Name < 'Cf') OR (Country > 'E' AND Country < 'F'))
|
||||
AND (Population > 101000 AND Population < 103000);
|
||||
AND (Population > 101000 AND Population < 102000);
|
||||
|
||||
# The output of the next 7 commands tells us about selectivities
|
||||
# of the conditions utilized in 4 queries following after them
|
||||
|
@ -197,9 +199,10 @@ SELECT * FROM City
|
|||
# of the conditions utilized in 3 queries following after them
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 50) OR (ID BETWEEN 100 AND 110);
|
||||
SELECT * FROM City WHERE (ID < 30) OR (ID BETWEEN 100 AND 150);
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 200) OR (ID BETWEEN 300 AND 600);
|
||||
--replace_result 2921 2950
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (ID < 600) OR (ID BETWEEN 900 AND 1800);
|
||||
EXPLAIN
|
||||
|
@ -219,7 +222,7 @@ SELECT * FROM City WHERE Name LIKE 'Ha%' OR Name LIKE 'Pa%' ;
|
|||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
|
||||
|
@ -240,12 +243,12 @@ SELECT * FROM City
|
|||
# for the previous 3 plans are valid
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ((ID < 50) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
WHERE ((ID < 30) AND (Name LIKE 'H%' OR (Country > 'A' AND Country < 'ARG')))
|
||||
OR ((ID BETWEEN 100 AND 110) AND
|
||||
(Name LIKE 'P%' OR (Population > 103000 AND Population < 104000)));
|
||||
|
||||
|
@ -361,7 +364,7 @@ SELECT * FROM City WHERE Name LIKE 'Pas%';
|
|||
EXPLAIN
|
||||
SELECT * FROM City WHERE Name LIKE 'P%';
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 103000);
|
||||
SELECT * FROM City WHERE (Population > 101000 AND Population < 102000);
|
||||
EXPLAIN
|
||||
SELECT * FROM City WHERE Country='USA';
|
||||
|
||||
|
@ -374,32 +377,32 @@ SELECT * FROM City WHERE Country='USA';
|
|||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%' )
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
|
||||
# The following 4 queries check that the plans
|
||||
# for the previous 2 plans are valid
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'Pas%')
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR Name LIKE 'Pas%')
|
||||
AND Country='USA';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 103000) OR Name LIKE 'P%')
|
||||
AND Country='USA';
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR Name LIKE 'P%')
|
||||
AND Country='USA' AND Name LIKE '%port';
|
||||
|
||||
|
||||
CREATE INDEX CountryName ON City(Country,Name);
|
||||
|
@ -463,9 +466,10 @@ SELECT * FROM City
|
|||
|
||||
EXPLAIN
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 110000) OR
|
||||
ID BETWEEN 3500 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'T' OR ID BETWEEN 4000 AND 4300);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
|
||||
# The following 6 queries check that the plans
|
||||
# for the previous 3 plans are valid
|
||||
|
@ -491,14 +495,16 @@ SELECT * FROM City
|
|||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4028 AND 4032);
|
||||
|
||||
SELECT * FROM City USE INDEX ()
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
|
||||
SELECT * FROM City
|
||||
WHERE ((Population > 101000 AND Population < 102000) OR
|
||||
ID BETWEEN 3790 AND 3800) AND Country='USA'
|
||||
AND (Name LIKE 'Pa%' OR ID BETWEEN 4025 AND 4035);
|
||||
WHERE ((Population > 101000 AND Population < 1000000) OR
|
||||
ID BETWEEN 3000 AND 3800) AND Country='USA'
|
||||
AND (Name BETWEEN 'P' AND 'Z' OR ID BETWEEN 3500 AND 4300)
|
||||
AND Name LIKE '%port';
|
||||
|
||||
|
||||
# The pattern of the WHERE condition used in the following query is
|
||||
|
@ -1003,3 +1009,6 @@ SELECT * FROM t1 FORCE KEY (PRIMARY,f3,f4)
|
|||
SET SESSION optimizer_switch=DEFAULT;
|
||||
|
||||
DROP TABLE t1;
|
||||
|
||||
#the following command must be the last one in the file
|
||||
set session optimizer_switch='index_merge_sort_intersection=default';
|
||||
|
|
|
@ -736,6 +736,7 @@ select * from information_schema.session_variables where variable_name like 'tmp
|
|||
# Bug #19606: make ssl settings available via SHOW VARIABLES and @@variables
|
||||
#
|
||||
# Don't actually output, since it depends on the system
|
||||
set sort_buffer_size=1024*8;
|
||||
--replace_column 1 # 2 # 3 # 4 # 5 #
|
||||
select @@ssl_ca, @@ssl_capath, @@ssl_cert, @@ssl_cipher, @@ssl_key;
|
||||
--replace_column 2 #
|
||||
|
|
|
@ -221,6 +221,8 @@ TREE_ELEMENT *tree_insert(TREE *tree, void *key, uint key_size,
|
|||
}
|
||||
if (element == &tree->null_element)
|
||||
{
|
||||
if (tree->flag & TREE_ONLY_DUPS)
|
||||
return((TREE_ELEMENT *) 1);
|
||||
uint alloc_size=sizeof(TREE_ELEMENT)+key_size+tree->size_of_element;
|
||||
tree->allocated+=alloc_size;
|
||||
|
||||
|
|
114
sql/filesort.cc
114
sql/filesort.cc
|
@ -50,10 +50,6 @@ static int write_keys(SORTPARAM *param,uchar * *sort_keys,
|
|||
uint count, IO_CACHE *buffer_file, IO_CACHE *tempfile);
|
||||
static void make_sortkey(SORTPARAM *param,uchar *to, uchar *ref_pos);
|
||||
static void register_used_fields(SORTPARAM *param);
|
||||
static int merge_index(SORTPARAM *param,uchar *sort_buffer,
|
||||
BUFFPEK *buffpek,
|
||||
uint maxbuffer,IO_CACHE *tempfile,
|
||||
IO_CACHE *outfile);
|
||||
static bool save_index(SORTPARAM *param,uchar **sort_keys, uint count,
|
||||
FILESORT_INFO *table_sort);
|
||||
static uint suffix_length(ulong string_length);
|
||||
|
@ -145,6 +141,7 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
|
|||
/* filesort cannot handle zero-length records. */
|
||||
DBUG_ASSERT(param.sort_length);
|
||||
param.ref_length= table->file->ref_length;
|
||||
param.min_dupl_count= 0;
|
||||
param.addon_field= 0;
|
||||
param.addon_length= 0;
|
||||
if (!(table->file->ha_table_flags() & HA_FAST_KEY_READ) &&
|
||||
|
@ -1216,7 +1213,13 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
rec_length= param->rec_length;
|
||||
res_length= param->res_length;
|
||||
sort_length= param->sort_length;
|
||||
offset= rec_length-res_length;
|
||||
element_count dupl_count;
|
||||
uchar *src;
|
||||
uint dupl_count_ofs= rec_length-sizeof(element_count);
|
||||
uint min_dupl_count= param->min_dupl_count;
|
||||
offset= rec_length-
|
||||
(flag && min_dupl_count ? sizeof(dupl_count) : 0)-res_length;
|
||||
uint wr_len= flag ? res_length : rec_length;
|
||||
maxcount= (ulong) (param->keys/((uint) (Tb-Fb) +1));
|
||||
to_start_filepos= my_b_tell(to_file);
|
||||
strpos= sort_buffer;
|
||||
|
@ -1262,16 +1265,20 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
*/
|
||||
buffpek= (BUFFPEK*) queue_top(&queue);
|
||||
memcpy(param->unique_buff, buffpek->key, rec_length);
|
||||
if (my_b_write(to_file, (uchar*) buffpek->key, rec_length))
|
||||
{
|
||||
error=1; goto err; /* purecov: inspected */
|
||||
}
|
||||
if (min_dupl_count)
|
||||
memcpy(&dupl_count, param->unique_buff+dupl_count_ofs,
|
||||
sizeof(dupl_count));
|
||||
buffpek->key+= rec_length;
|
||||
buffpek->mem_count--;
|
||||
if (!--max_rows)
|
||||
if (! --buffpek->mem_count)
|
||||
{
|
||||
error= 0; /* purecov: inspected */
|
||||
goto end; /* purecov: inspected */
|
||||
if (!(error= (int) read_to_buffer(from_file,buffpek,
|
||||
rec_length)))
|
||||
{
|
||||
VOID(queue_remove(&queue,0));
|
||||
reuse_freed_buff(&queue, buffpek, rec_length);
|
||||
}
|
||||
else if (error == -1)
|
||||
goto err; /* purecov: inspected */
|
||||
}
|
||||
queue_replaced(&queue); // Top element has been used
|
||||
}
|
||||
|
@ -1287,26 +1294,41 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
for (;;)
|
||||
{
|
||||
buffpek= (BUFFPEK*) queue_top(&queue);
|
||||
src= buffpek->key;
|
||||
if (cmp) // Remove duplicates
|
||||
{
|
||||
if (!(*cmp)(first_cmp_arg, &(param->unique_buff),
|
||||
(uchar**) &buffpek->key))
|
||||
goto skip_duplicate;
|
||||
memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
|
||||
{
|
||||
if (min_dupl_count)
|
||||
{
|
||||
element_count cnt;
|
||||
memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt));
|
||||
dupl_count+= cnt;
|
||||
}
|
||||
goto skip_duplicate;
|
||||
}
|
||||
if (min_dupl_count)
|
||||
{
|
||||
memcpy(param->unique_buff+dupl_count_ofs, &dupl_count,
|
||||
sizeof(dupl_count));
|
||||
}
|
||||
src= param->unique_buff;
|
||||
}
|
||||
if (flag == 0)
|
||||
|
||||
if (!flag || !min_dupl_count || dupl_count >= min_dupl_count)
|
||||
{
|
||||
if (my_b_write(to_file,(uchar*) buffpek->key, rec_length))
|
||||
if (my_b_write(to_file, src+(flag ? offset : 0), wr_len))
|
||||
{
|
||||
error=1; goto err; /* purecov: inspected */
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (my_b_write(to_file, (uchar*) buffpek->key+offset, res_length))
|
||||
{
|
||||
error=1; goto err; /* purecov: inspected */
|
||||
}
|
||||
if (cmp)
|
||||
{
|
||||
memcpy(param->unique_buff, (uchar*) buffpek->key, rec_length);
|
||||
if (min_dupl_count)
|
||||
memcpy(&dupl_count, param->unique_buff+dupl_count_ofs,
|
||||
sizeof(dupl_count));
|
||||
}
|
||||
if (!--max_rows)
|
||||
{
|
||||
|
@ -1343,9 +1365,33 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
{
|
||||
if (!(*cmp)(first_cmp_arg, &(param->unique_buff), (uchar**) &buffpek->key))
|
||||
{
|
||||
buffpek->key+= rec_length; // Remove duplicate
|
||||
if (min_dupl_count)
|
||||
{
|
||||
element_count cnt;
|
||||
memcpy(&cnt, (uchar *) buffpek->key+dupl_count_ofs, sizeof(cnt));
|
||||
dupl_count+= cnt;
|
||||
}
|
||||
buffpek->key+= rec_length;
|
||||
--buffpek->mem_count;
|
||||
}
|
||||
|
||||
if (min_dupl_count)
|
||||
memcpy(param->unique_buff+dupl_count_ofs, &dupl_count,
|
||||
sizeof(dupl_count));
|
||||
|
||||
if (!flag || !min_dupl_count || dupl_count >= min_dupl_count)
|
||||
{
|
||||
src= param->unique_buff;
|
||||
if (my_b_write(to_file, src+(flag ? offset : 0), wr_len))
|
||||
{
|
||||
error=1; goto err; /* purecov: inspected */
|
||||
}
|
||||
if (!--max_rows)
|
||||
{
|
||||
error= 0;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
do
|
||||
|
@ -1367,12 +1413,17 @@ int merge_buffers(SORTPARAM *param, IO_CACHE *from_file,
|
|||
else
|
||||
{
|
||||
register uchar *end;
|
||||
strpos= buffpek->key+offset;
|
||||
for (end= strpos+buffpek->mem_count*rec_length ;
|
||||
strpos != end ;
|
||||
strpos+= rec_length)
|
||||
{
|
||||
if (my_b_write(to_file, strpos, res_length))
|
||||
src= buffpek->key+offset;
|
||||
for (end= src+buffpek->mem_count*rec_length ;
|
||||
src != end ;
|
||||
src+= rec_length)
|
||||
{
|
||||
if (flag && min_dupl_count &&
|
||||
memcmp(&min_dupl_count, src+dupl_count_ofs,
|
||||
sizeof(dupl_count_ofs))<0)
|
||||
continue;
|
||||
|
||||
if (my_b_write(to_file, src, wr_len))
|
||||
{
|
||||
error=1; goto err;
|
||||
}
|
||||
|
@ -1393,7 +1444,7 @@ err:
|
|||
|
||||
/* Do a merge to output-file (save only positions) */
|
||||
|
||||
static int merge_index(SORTPARAM *param, uchar *sort_buffer,
|
||||
int merge_index(SORTPARAM *param, uchar *sort_buffer,
|
||||
BUFFPEK *buffpek, uint maxbuffer,
|
||||
IO_CACHE *tempfile, IO_CACHE *outfile)
|
||||
{
|
||||
|
@ -1699,3 +1750,4 @@ void change_double_for_sort(double nr,uchar *to)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -338,7 +338,7 @@ protected:
|
|||
Number of comparisons of table rowids equivalent to reading one row from a
|
||||
table.
|
||||
*/
|
||||
#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*2)
|
||||
#define TIME_FOR_COMPARE_ROWID (TIME_FOR_COMPARE*100)
|
||||
|
||||
/*
|
||||
For sequential disk seeks the cost formula is:
|
||||
|
@ -542,12 +542,13 @@ protected:
|
|||
#define OPTIMIZER_SWITCH_INDEX_MERGE_UNION 2
|
||||
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION 4
|
||||
#define OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT 8
|
||||
#define OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT 16
|
||||
|
||||
#ifdef DBUG_OFF
|
||||
# define OPTIMIZER_SWITCH_LAST 16
|
||||
#else
|
||||
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 16
|
||||
# define OPTIMIZER_SWITCH_LAST 32
|
||||
#else
|
||||
# define OPTIMIZER_SWITCH_TABLE_ELIMINATION 32
|
||||
# define OPTIMIZER_SWITCH_LAST 64
|
||||
#endif
|
||||
|
||||
#ifdef DBUG_OFF
|
||||
|
@ -555,12 +556,14 @@ protected:
|
|||
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT)
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT)
|
||||
#else
|
||||
# define OPTIMIZER_SWITCH_DEFAULT (OPTIMIZER_SWITCH_INDEX_MERGE | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_UNION | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_UNION | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_INTERSECT | \
|
||||
OPTIMIZER_SWITCH_INDEX_MERGE_SORT_INTERSECT | \
|
||||
OPTIMIZER_SWITCH_TABLE_ELIMINATION)
|
||||
#endif
|
||||
|
||||
|
@ -2233,6 +2236,8 @@ ha_rows filesort(THD *thd, TABLE *form,struct st_sort_field *sortorder,
|
|||
ha_rows max_rows, bool sort_positions,
|
||||
ha_rows *examined_rows);
|
||||
void filesort_free_buffers(TABLE *table, bool full);
|
||||
double get_merge_many_buffs_cost(uint *buffer, uint last_n_elems,
|
||||
int elem_size);
|
||||
void change_double_for_sort(double nr,uchar *to);
|
||||
double my_double_round(double value, longlong dec, bool dec_unsigned,
|
||||
bool truncate);
|
||||
|
|
|
@ -338,7 +338,7 @@ TYPELIB sql_mode_typelib= { array_elements(sql_mode_names)-1,"",
|
|||
static const char *optimizer_switch_names[]=
|
||||
{
|
||||
"index_merge","index_merge_union","index_merge_sort_union",
|
||||
"index_merge_intersection",
|
||||
"index_merge_intersection","index_merge_sort_intersection",
|
||||
#ifndef DBUG_OFF
|
||||
"table_elimination",
|
||||
#endif
|
||||
|
@ -352,6 +352,7 @@ static const unsigned int optimizer_switch_names_len[]=
|
|||
sizeof("index_merge_union") - 1,
|
||||
sizeof("index_merge_sort_union") - 1,
|
||||
sizeof("index_merge_intersection") - 1,
|
||||
sizeof("index_merge_sort_intersection") - 1,
|
||||
#ifndef DBUG_OFF
|
||||
sizeof("table_elimination") - 1,
|
||||
#endif
|
||||
|
@ -431,7 +432,8 @@ static const char *sql_mode_str= "OFF";
|
|||
/* Text representation for OPTIMIZER_SWITCH_DEFAULT */
|
||||
static const char *optimizer_switch_str="index_merge=on,index_merge_union=on,"
|
||||
"index_merge_sort_union=on,"
|
||||
"index_merge_intersection=on"
|
||||
"index_merge_intersection=on,"
|
||||
"index_merge_sort_intersection=on"
|
||||
#ifndef DBUG_OFF
|
||||
",table_elimination=on";
|
||||
#else
|
||||
|
@ -7297,7 +7299,8 @@ thread is in the relay logs.",
|
|||
0, GET_ULONG, OPT_ARG, MAX_TABLES+1, 0, MAX_TABLES+2, 0, 1, 0},
|
||||
{"optimizer_switch", OPT_OPTIMIZER_SWITCH,
|
||||
"optimizer_switch=option=val[,option=val...], where option={index_merge, "
|
||||
"index_merge_union, index_merge_sort_union, index_merge_intersection"
|
||||
"index_merge_union, index_merge_sort_union, index_merge_intersection, "
|
||||
"index_merge_sort_intersection"
|
||||
#ifndef DBUG_OFF
|
||||
", table_elimination"
|
||||
#endif
|
||||
|
|
1147
sql/opt_range.cc
1147
sql/opt_range.cc
File diff suppressed because it is too large
Load diff
|
@ -274,12 +274,13 @@ public:
|
|||
|
||||
enum {
|
||||
QS_TYPE_RANGE = 0,
|
||||
QS_TYPE_INDEX_MERGE = 1,
|
||||
QS_TYPE_RANGE_DESC = 2,
|
||||
QS_TYPE_FULLTEXT = 3,
|
||||
QS_TYPE_ROR_INTERSECT = 4,
|
||||
QS_TYPE_ROR_UNION = 5,
|
||||
QS_TYPE_GROUP_MIN_MAX = 6
|
||||
QS_TYPE_INDEX_INTERSECT = 1,
|
||||
QS_TYPE_INDEX_MERGE = 2,
|
||||
QS_TYPE_RANGE_DESC = 3,
|
||||
QS_TYPE_FULLTEXT = 4,
|
||||
QS_TYPE_ROR_INTERSECT = 5,
|
||||
QS_TYPE_ROR_UNION = 6,
|
||||
QS_TYPE_GROUP_MIN_MAX = 7
|
||||
};
|
||||
|
||||
/* Get type of this quick select - one of the QS_TYPE_* values */
|
||||
|
@ -305,6 +306,10 @@ public:
|
|||
Save ROWID of last retrieved row in file->ref. This used in ROR-merging.
|
||||
*/
|
||||
virtual void save_last_pos(){};
|
||||
|
||||
void add_key_and_length(String *key_names,
|
||||
String *used_lengths,
|
||||
bool *first);
|
||||
|
||||
/*
|
||||
Append comma-separated list of keys this quick select uses to key_names;
|
||||
|
@ -314,13 +319,15 @@ public:
|
|||
virtual void add_keys_and_lengths(String *key_names,
|
||||
String *used_lengths)=0;
|
||||
|
||||
void add_key_name(String *str, bool *first);
|
||||
|
||||
/*
|
||||
Append text representation of quick select structure (what and how is
|
||||
merged) to str. The result is added to "Extra" field in EXPLAIN output.
|
||||
This function is implemented only by quick selects that merge other quick
|
||||
selects output and/or can produce output suitable for merging.
|
||||
*/
|
||||
virtual void add_info_string(String *str) {};
|
||||
virtual void add_info_string(String *str) {}
|
||||
/*
|
||||
Return 1 if any index used by this quick select
|
||||
uses field which is marked in passed bitmap.
|
||||
|
@ -393,8 +400,17 @@ protected:
|
|||
friend QUICK_RANGE_SELECT *get_quick_select(PARAM*,uint idx,
|
||||
SEL_ARG *key_tree,
|
||||
MEM_ROOT *alloc);
|
||||
friend
|
||||
int read_keys_and_merge_scans(THD *thd, TABLE *head,
|
||||
List<QUICK_RANGE_SELECT> quick_selects,
|
||||
QUICK_RANGE_SELECT *pk_quick_select,
|
||||
READ_RECORD *read_record,
|
||||
bool intersection,
|
||||
Unique **unique_ptr);
|
||||
|
||||
friend class QUICK_SELECT_DESC;
|
||||
friend class QUICK_INDEX_MERGE_SELECT;
|
||||
friend class QUICK_INDEX_INTERSECT_SELECT;
|
||||
friend class QUICK_ROR_INTERSECT_SELECT;
|
||||
friend class QUICK_GROUP_MIN_MAX_SELECT;
|
||||
|
||||
|
@ -545,6 +561,45 @@ public:
|
|||
READ_RECORD read_record;
|
||||
};
|
||||
|
||||
class QUICK_INDEX_INTERSECT_SELECT : public QUICK_SELECT_I
|
||||
{
|
||||
Unique *unique;
|
||||
public:
|
||||
QUICK_INDEX_INTERSECT_SELECT(THD *thd, TABLE *table);
|
||||
~QUICK_INDEX_INTERSECT_SELECT();
|
||||
|
||||
int init();
|
||||
int reset(void);
|
||||
int get_next();
|
||||
bool reverse_sorted() { return false; }
|
||||
bool unique_key_range() { return false; }
|
||||
int get_type() { return QS_TYPE_INDEX_INTERSECT; }
|
||||
void add_keys_and_lengths(String *key_names, String *used_lengths);
|
||||
void add_info_string(String *str);
|
||||
bool is_keys_used(const MY_BITMAP *fields);
|
||||
#ifndef DBUG_OFF
|
||||
void dbug_dump(int indent, bool verbose);
|
||||
#endif
|
||||
|
||||
bool push_quick_back(QUICK_RANGE_SELECT *quick_sel_range);
|
||||
|
||||
/* range quick selects this index_merge read consists of */
|
||||
List<QUICK_RANGE_SELECT> quick_selects;
|
||||
|
||||
/* quick select that uses clustered primary key (NULL if none) */
|
||||
QUICK_RANGE_SELECT* pk_quick_select;
|
||||
|
||||
/* true if this select is currently doing a clustered PK scan */
|
||||
bool doing_pk_scan;
|
||||
|
||||
MEM_ROOT alloc;
|
||||
THD *thd;
|
||||
int read_keys_and_merge();
|
||||
|
||||
/* used to get rows collected in Unique */
|
||||
READ_RECORD read_record;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Rowid-Ordered Retrieval (ROR) index intersection quick select.
|
||||
|
|
|
@ -2977,6 +2977,7 @@ class user_var_entry
|
|||
DTCollation collation;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
Unique -- class for unique (removing of duplicates).
|
||||
Puts all values to the TREE. If the tree becomes too big,
|
||||
|
@ -2993,27 +2994,42 @@ class Unique :public Sql_alloc
|
|||
IO_CACHE file;
|
||||
TREE tree;
|
||||
uchar *record_pointers;
|
||||
ulong filtered_out_elems;
|
||||
bool flush();
|
||||
uint size;
|
||||
uint full_size;
|
||||
uint min_dupl_count;
|
||||
|
||||
public:
|
||||
ulong elements;
|
||||
Unique(qsort_cmp2 comp_func, void *comp_func_fixed_arg,
|
||||
uint size_arg, ulonglong max_in_memory_size_arg);
|
||||
uint size_arg, ulonglong max_in_memory_size_arg,
|
||||
uint min_dupl_count_arg= 0);
|
||||
~Unique();
|
||||
ulong elements_in_tree() { return tree.elements_in_tree; }
|
||||
inline bool unique_add(void *ptr)
|
||||
{
|
||||
DBUG_ENTER("unique_add");
|
||||
DBUG_PRINT("info", ("tree %u - %lu", tree.elements_in_tree, max_elements));
|
||||
if (tree.elements_in_tree > max_elements && flush())
|
||||
if (!(tree.flag & TREE_ONLY_DUPS) &&
|
||||
tree.elements_in_tree >= max_elements && flush())
|
||||
DBUG_RETURN(1);
|
||||
DBUG_RETURN(!tree_insert(&tree, ptr, 0, tree.custom_arg));
|
||||
}
|
||||
|
||||
bool is_in_memory() { return (my_b_tell(&file) == 0); }
|
||||
void close_for_expansion() { tree.flag= TREE_ONLY_DUPS; }
|
||||
|
||||
bool get(TABLE *table);
|
||||
|
||||
inline static double get_search_cost(uint tree_elems, uint compare_factor)
|
||||
{
|
||||
return log((double) tree_elems) / (compare_factor * M_LN2);
|
||||
}
|
||||
|
||||
static double get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
||||
ulonglong max_in_memory_size);
|
||||
ulonglong max_in_memory_size, uint compare_factor,
|
||||
bool intersect_fl, bool *in_memory);
|
||||
inline static int get_cost_calc_buff_size(ulong nkeys, uint key_size,
|
||||
ulonglong max_in_memory_size)
|
||||
{
|
||||
|
@ -3030,6 +3046,11 @@ public:
|
|||
|
||||
friend int unique_write_to_file(uchar* key, element_count count, Unique *unique);
|
||||
friend int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique);
|
||||
|
||||
friend int unique_write_to_file_with_count(uchar* key, element_count count,
|
||||
Unique *unique);
|
||||
friend int unique_intersect_write_to_ptrs(uchar* key, element_count count,
|
||||
Unique *unique);
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -2688,6 +2688,7 @@ make_join_statistics(JOIN *join, TABLE_LIST *tables_arg, COND *conds,
|
|||
goto error;
|
||||
}
|
||||
table->quick_keys.clear_all();
|
||||
table->intersect_keys.clear_all();
|
||||
table->reginfo.join_tab=s;
|
||||
table->reginfo.not_exists_optimize=0;
|
||||
bzero((char*) table->const_key_parts, sizeof(key_part_map)*table->s->keys);
|
||||
|
@ -6373,8 +6374,10 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
|
|||
used_tables|=current_map;
|
||||
|
||||
if (tab->type == JT_REF && tab->quick &&
|
||||
(uint) tab->ref.key == tab->quick->index &&
|
||||
tab->ref.key_length < tab->quick->max_used_key_length)
|
||||
(((uint) tab->ref.key == tab->quick->index &&
|
||||
tab->ref.key_length < tab->quick->max_used_key_length) ||
|
||||
(!tab->table->intersect_keys.is_clear_all() &&
|
||||
tab->table->intersect_keys.is_set(tab->ref.key))))
|
||||
{
|
||||
/* Range uses longer key; Use this instead of ref on key */
|
||||
tab->type=JT_ALL;
|
||||
|
@ -10186,6 +10189,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
|
|||
table->quick_keys.init();
|
||||
table->covering_keys.init();
|
||||
table->merge_keys.init();
|
||||
table->intersect_keys.init();
|
||||
table->keys_in_use_for_query.init();
|
||||
|
||||
table->s= share;
|
||||
|
@ -13678,7 +13682,8 @@ test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order,ha_rows select_limit,
|
|||
by clustered PK values.
|
||||
*/
|
||||
|
||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT)
|
||||
DBUG_RETURN(0);
|
||||
|
@ -14084,6 +14089,7 @@ check_reverse_order:
|
|||
QUICK_SELECT_DESC *tmp;
|
||||
int quick_type= select->quick->get_type();
|
||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_GROUP_MIN_MAX)
|
||||
|
@ -14256,6 +14262,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order,
|
|||
select->cleanup(); // filesort did select
|
||||
tab->select= 0;
|
||||
table->quick_keys.clear_all(); // as far as we cleanup select->quick
|
||||
table->intersect_keys.clear_all();
|
||||
table->sort.io_cache= tablesort_result_cache;
|
||||
}
|
||||
tab->select_cond=0;
|
||||
|
@ -16879,6 +16886,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||
{
|
||||
quick_type= tab->select->quick->get_type();
|
||||
if ((quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE) ||
|
||||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
|
||||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT) ||
|
||||
(quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION))
|
||||
tab->type = JT_INDEX_MERGE;
|
||||
|
@ -17092,6 +17100,7 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
|
|||
{
|
||||
if (quick_type == QUICK_SELECT_I::QS_TYPE_ROR_UNION ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_ROR_INTERSECT ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_INTERSECT ||
|
||||
quick_type == QUICK_SELECT_I::QS_TYPE_INDEX_MERGE)
|
||||
{
|
||||
extra.append(STRING_WITH_LEN("; Using "));
|
||||
|
|
|
@ -57,6 +57,7 @@ typedef struct st_sort_param {
|
|||
uint addon_length; /* Length of added packed fields */
|
||||
uint res_length; /* Length of records in final sorted file/buffer */
|
||||
uint keys; /* Max keys / buffer */
|
||||
element_count min_dupl_count;
|
||||
ha_rows max_rows,examined_rows;
|
||||
TABLE *sort_form; /* For quicker make_sortkey */
|
||||
SORT_FIELD *local_sortorder;
|
||||
|
@ -80,4 +81,9 @@ int merge_buffers(SORTPARAM *param,IO_CACHE *from_file,
|
|||
IO_CACHE *to_file, uchar *sort_buffer,
|
||||
BUFFPEK *lastbuff,BUFFPEK *Fb,
|
||||
BUFFPEK *Tb,int flag);
|
||||
int merge_index(SORTPARAM *param, uchar *sort_buffer,
|
||||
BUFFPEK *buffpek, uint maxbuffer,
|
||||
IO_CACHE *tempfile, IO_CACHE *outfile);
|
||||
|
||||
void reuse_freed_buff(QUEUE *queue, BUFFPEK *reuse, uint key_length);
|
||||
|
||||
|
|
|
@ -683,7 +683,7 @@ struct st_table {
|
|||
needed by the query without reading the row.
|
||||
*/
|
||||
key_map covering_keys;
|
||||
key_map quick_keys, merge_keys;
|
||||
key_map quick_keys, merge_keys,intersect_keys;
|
||||
/*
|
||||
A set of keys that can be used in the query that references this
|
||||
table.
|
||||
|
|
|
@ -33,7 +33,6 @@
|
|||
#include "mysql_priv.h"
|
||||
#include "sql_sort.h"
|
||||
|
||||
|
||||
int unique_write_to_file(uchar* key, element_count count, Unique *unique)
|
||||
{
|
||||
/*
|
||||
|
@ -45,6 +44,12 @@ int unique_write_to_file(uchar* key, element_count count, Unique *unique)
|
|||
return my_b_write(&unique->file, key, unique->size) ? 1 : 0;
|
||||
}
|
||||
|
||||
int unique_write_to_file_with_count(uchar* key, element_count count, Unique *unique)
|
||||
{
|
||||
return my_b_write(&unique->file, key, unique->size) ||
|
||||
my_b_write(&unique->file, &count, sizeof(element_count)) ? 1 : 0;
|
||||
}
|
||||
|
||||
int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
|
||||
{
|
||||
memcpy(unique->record_pointers, key, unique->size);
|
||||
|
@ -52,10 +57,28 @@ int unique_write_to_ptrs(uchar* key, element_count count, Unique *unique)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int unique_intersect_write_to_ptrs(uchar* key, element_count count, Unique *unique)
|
||||
{
|
||||
if (count >= unique->min_dupl_count)
|
||||
{
|
||||
memcpy(unique->record_pointers, key, unique->size);
|
||||
unique->record_pointers+=unique->size;
|
||||
}
|
||||
else
|
||||
unique->filtered_out_elems++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg,
|
||||
uint size_arg, ulonglong max_in_memory_size_arg)
|
||||
uint size_arg, ulonglong max_in_memory_size_arg,
|
||||
uint min_dupl_count_arg)
|
||||
:max_in_memory_size(max_in_memory_size_arg), size(size_arg), elements(0)
|
||||
{
|
||||
min_dupl_count= min_dupl_count_arg;
|
||||
full_size= size;
|
||||
if (min_dupl_count_arg)
|
||||
full_size+= sizeof(element_count);
|
||||
my_b_clear(&file);
|
||||
init_tree(&tree, (ulong) (max_in_memory_size / 16), 0, size, comp_func, 0,
|
||||
NULL, comp_func_fixed_arg);
|
||||
|
@ -123,7 +146,8 @@ inline double log2_n_fact(double x)
|
|||
*/
|
||||
|
||||
static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
||||
uint *first, uint *last)
|
||||
uint *first, uint *last,
|
||||
uint compare_factor)
|
||||
{
|
||||
uint total_buf_elems= 0;
|
||||
for (uint *pbuf= first; pbuf <= last; pbuf++)
|
||||
|
@ -134,7 +158,7 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
|||
|
||||
/* Using log2(n)=log(n)/log(2) formula */
|
||||
return 2*((double)total_buf_elems*elem_size) / IO_SIZE +
|
||||
total_buf_elems*log((double) n_buffers) / (TIME_FOR_COMPARE_ROWID * M_LN2);
|
||||
total_buf_elems*log((double) n_buffers) / (compare_factor * M_LN2);
|
||||
}
|
||||
|
||||
|
||||
|
@ -167,7 +191,8 @@ static double get_merge_buffers_cost(uint *buff_elems, uint elem_size,
|
|||
|
||||
static double get_merge_many_buffs_cost(uint *buffer,
|
||||
uint maxbuffer, uint max_n_elems,
|
||||
uint last_n_elems, int elem_size)
|
||||
uint last_n_elems, int elem_size,
|
||||
uint compare_factor)
|
||||
{
|
||||
register int i;
|
||||
double total_cost= 0.0;
|
||||
|
@ -194,19 +219,22 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
{
|
||||
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems + i,
|
||||
buff_elems + i + MERGEBUFF-1);
|
||||
buff_elems + i + MERGEBUFF-1,
|
||||
compare_factor);
|
||||
lastbuff++;
|
||||
}
|
||||
total_cost+=get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems + i,
|
||||
buff_elems + maxbuffer);
|
||||
buff_elems + maxbuffer,
|
||||
compare_factor);
|
||||
maxbuffer= lastbuff;
|
||||
}
|
||||
}
|
||||
|
||||
/* Simulate final merge_buff call. */
|
||||
total_cost += get_merge_buffers_cost(buff_elems, elem_size,
|
||||
buff_elems, buff_elems + maxbuffer);
|
||||
buff_elems, buff_elems + maxbuffer,
|
||||
compare_factor);
|
||||
return total_cost;
|
||||
}
|
||||
|
||||
|
@ -221,7 +249,11 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
to get # bytes needed.
|
||||
nkeys #of elements in Unique
|
||||
key_size size of each elements in bytes
|
||||
max_in_memory_size amount of memory Unique will be allowed to use
|
||||
max_in_memory_size amount of memory Unique will be allowed to use
|
||||
compare_factor used to calculate cost of one comparison
|
||||
write_fl if the result must be saved written to disk
|
||||
in_memory_elems OUT estimate of the number of elements in memory
|
||||
if disk is not used
|
||||
|
||||
RETURN
|
||||
Cost in disk seeks.
|
||||
|
@ -259,7 +291,9 @@ static double get_merge_many_buffs_cost(uint *buffer,
|
|||
*/
|
||||
|
||||
double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
||||
ulonglong max_in_memory_size)
|
||||
ulonglong max_in_memory_size,
|
||||
uint compare_factor,
|
||||
bool intersect_fl, bool *in_memory)
|
||||
{
|
||||
ulong max_elements_in_tree;
|
||||
ulong last_tree_elems;
|
||||
|
@ -276,12 +310,15 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
|||
result= 2*log2_n_fact(last_tree_elems + 1.0);
|
||||
if (n_full_trees)
|
||||
result+= n_full_trees * log2_n_fact(max_elements_in_tree + 1.0);
|
||||
result /= TIME_FOR_COMPARE_ROWID;
|
||||
result /= compare_factor;
|
||||
|
||||
DBUG_PRINT("info",("unique trees sizes: %u=%u*%lu + %lu", nkeys,
|
||||
n_full_trees, n_full_trees?max_elements_in_tree:0,
|
||||
last_tree_elems));
|
||||
|
||||
if (in_memory)
|
||||
*in_memory= !n_full_trees;
|
||||
|
||||
if (!n_full_trees)
|
||||
return result;
|
||||
|
||||
|
@ -295,12 +332,12 @@ double Unique::get_use_cost(uint *buffer, uint nkeys, uint key_size,
|
|||
result += DISK_SEEK_BASE_COST * ceil(((double) key_size)*last_tree_elems / IO_SIZE);
|
||||
|
||||
/* Cost of merge */
|
||||
if (intersect_fl)
|
||||
key_size+= sizeof(element_count);
|
||||
double merge_cost= get_merge_many_buffs_cost(buffer, n_full_trees,
|
||||
max_elements_in_tree,
|
||||
last_tree_elems, key_size);
|
||||
if (merge_cost < 0.0)
|
||||
return merge_cost;
|
||||
|
||||
last_tree_elems, key_size,
|
||||
compare_factor);
|
||||
result += merge_cost;
|
||||
/*
|
||||
Add cost of reading the resulting sequence, assuming there were no
|
||||
|
@ -327,7 +364,10 @@ bool Unique::flush()
|
|||
file_ptr.count=tree.elements_in_tree;
|
||||
file_ptr.file_pos=my_b_tell(&file);
|
||||
|
||||
if (tree_walk(&tree, (tree_walk_action) unique_write_to_file,
|
||||
tree_walk_action action= min_dupl_count ?
|
||||
(tree_walk_action) unique_write_to_file_with_count :
|
||||
(tree_walk_action) unique_write_to_file;
|
||||
if (tree_walk(&tree, action,
|
||||
(void*) this, left_root_right) ||
|
||||
insert_dynamic(&file_ptrs, (uchar*) &file_ptr))
|
||||
return 1;
|
||||
|
@ -357,6 +397,7 @@ Unique::reset()
|
|||
reinit_io_cache(&file, WRITE_CACHE, 0L, 0, 1);
|
||||
}
|
||||
elements= 0;
|
||||
tree.flag= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -576,15 +617,19 @@ bool Unique::get(TABLE *table)
|
|||
{
|
||||
SORTPARAM sort_param;
|
||||
table->sort.found_records=elements+tree.elements_in_tree;
|
||||
|
||||
if (my_b_tell(&file) == 0)
|
||||
{
|
||||
/* Whole tree is in memory; Don't use disk if you don't need to */
|
||||
if ((record_pointers=table->sort.record_pointers= (uchar*)
|
||||
my_malloc(size * tree.elements_in_tree, MYF(0))))
|
||||
{
|
||||
(void) tree_walk(&tree, (tree_walk_action) unique_write_to_ptrs,
|
||||
tree_walk_action action= min_dupl_count ?
|
||||
(tree_walk_action) unique_intersect_write_to_ptrs :
|
||||
(tree_walk_action) unique_write_to_ptrs;
|
||||
filtered_out_elems= 0;
|
||||
(void) tree_walk(&tree, action,
|
||||
this, left_root_right);
|
||||
table->sort.found_records-= filtered_out_elems;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
@ -614,7 +659,9 @@ bool Unique::get(TABLE *table)
|
|||
sort_param.max_rows= elements;
|
||||
sort_param.sort_form=table;
|
||||
sort_param.rec_length= sort_param.sort_length= sort_param.ref_length=
|
||||
size;
|
||||
full_size;
|
||||
sort_param.min_dupl_count= min_dupl_count;
|
||||
sort_param.res_length= 0;
|
||||
sort_param.keys= (uint) (max_in_memory_size / sort_param.sort_length);
|
||||
sort_param.not_killable=1;
|
||||
|
||||
|
@ -635,8 +682,9 @@ bool Unique::get(TABLE *table)
|
|||
if (flush_io_cache(&file) ||
|
||||
reinit_io_cache(&file,READ_CACHE,0L,0,0))
|
||||
goto err;
|
||||
if (merge_buffers(&sort_param, &file, outfile, sort_buffer, file_ptr,
|
||||
file_ptr, file_ptr+maxbuffer,0))
|
||||
sort_param.res_length= sort_param.rec_length-
|
||||
(min_dupl_count ? sizeof(min_dupl_count) : 0);
|
||||
if (merge_index(&sort_param, sort_buffer, file_ptr, maxbuffer, &file, outfile))
|
||||
goto err;
|
||||
error=0;
|
||||
err:
|
||||
|
@ -651,3 +699,5 @@ err:
|
|||
outfile->end_of_file=save_pos;
|
||||
return error;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -89,7 +89,7 @@
|
|||
#define MAX_SELECT_NESTING (sizeof(nesting_map)*8-1)
|
||||
|
||||
#define MAX_SORT_MEMORY (2048*1024-MALLOC_OVERHEAD)
|
||||
#define MIN_SORT_MEMORY (32*1024-MALLOC_OVERHEAD)
|
||||
#define MIN_SORT_MEMORY (1024-MALLOC_OVERHEAD)
|
||||
|
||||
/* Memory allocated when parsing a statement / saving a statement */
|
||||
#define MEM_ROOT_BLOCK_SIZE 8192
|
||||
|
|
Loading…
Reference in a new issue