Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
M
MariaDB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
nexedi
MariaDB
Commits
24c18094
Commit
24c18094
authored
Dec 09, 2003
by
sergefp@mysql.com
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Two-sweeps read index_merge plus several small index_merge fixes and improvements
parent
3d32afd7
Changes
12
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
12 changed files
with
666 additions
and
58 deletions
+666
-58
mysql-test/r/index_merge_bdb.result
mysql-test/r/index_merge_bdb.result
+136
-0
mysql-test/r/index_merge_innodb2.result
mysql-test/r/index_merge_innodb2.result
+136
-0
mysql-test/t/index_merge_bdb.test
mysql-test/t/index_merge_bdb.test
+52
-0
mysql-test/t/index_merge_innodb2.test
mysql-test/t/index_merge_innodb2.test
+52
-0
sql/filesort.cc
sql/filesort.cc
+14
-3
sql/ha_berkeley.h
sql/ha_berkeley.h
+1
-0
sql/ha_innodb.cc
sql/ha_innodb.cc
+6
-4
sql/ha_innodb.h
sql/ha_innodb.h
+1
-0
sql/handler.h
sql/handler.h
+7
-0
sql/opt_range.cc
sql/opt_range.cc
+182
-41
sql/opt_range.h
sql/opt_range.h
+77
-8
sql/records.cc
sql/records.cc
+2
-2
No files found.
mysql-test/r/index_merge_bdb.result
0 → 100644
View file @
24c18094
drop table if exists t1;
create table t1 (
pk int primary key,
key1 int,
key2 int,
filler char(200),
filler2 char(200),
index(key1),
index(key2),
) type=bdb;
select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
pk key1 key2 filler filler2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
9 9 9 filler-data filler-data-2
10 10 10 filler-data filler-data-2
4 4 4 filler-data filler-data-2
5 5 5 filler-data filler-data-2
6 6 6 filler-data filler-data-2
7 7 7 filler-data filler-data-2
8 8 8 filler-data filler-data-2
set @maxv=1000;
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1=18 or key1=60;
pk key1 key2 filler filler2
18 18 18 filler-data filler-data-2
60 60 60 filler-data filler-data-2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1 < 3 or key1 > @maxv-11;
pk key1 key2 filler filler2
990 990 990 filler-data filler-data-2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or
(key1 < 5) or (key1 > 10 and key1 < 15) or (key1 >= 50 and key1 < 55 ) or (key1 > @maxv-10);
pk key1 key2 filler filler2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk > 10 and pk < 15) or (pk >= 50 and pk < 55 )
or
(key1 < 5) or (key1 > @maxv-10);
pk key1 key2 filler filler2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
drop table t1;
mysql-test/r/index_merge_innodb2.result
0 → 100644
View file @
24c18094
drop table if exists t1;
create table t1 (
pk int primary key,
key1 int,
key2 int,
filler char(200),
filler2 char(200),
index(key1),
index(key2),
) type=innodb;
select * from t1 where (key1 >= 2 and key1 <= 10) or (pk >= 4 and pk <=8 );
pk key1 key2 filler filler2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
9 9 9 filler-data filler-data-2
10 10 10 filler-data filler-data-2
4 4 4 filler-data filler-data-2
5 5 5 filler-data filler-data-2
6 6 6 filler-data filler-data-2
7 7 7 filler-data filler-data-2
8 8 8 filler-data filler-data-2
set @maxv=1000;
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1=18 or key1=60;
pk key1 key2 filler filler2
18 18 18 filler-data filler-data-2
60 60 60 filler-data filler-data-2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or key1 < 3 or key1 > @maxv-11;
pk key1 key2 filler filler2
990 990 990 filler-data filler-data-2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk < 5) or (pk > 10 and pk < 15) or (pk >= 50 and pk < 55 ) or (pk > @maxv-10)
or
(key1 < 5) or (key1 > 10 and key1 < 15) or (key1 >= 50 and key1 < 55 ) or (key1 > @maxv-10);
pk key1 key2 filler filler2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
select * from t1 where
(pk > 10 and pk < 15) or (pk >= 50 and pk < 55 )
or
(key1 < 5) or (key1 > @maxv-10);
pk key1 key2 filler filler2
1 1 1 filler-data filler-data-2
2 2 2 filler-data filler-data-2
3 3 3 filler-data filler-data-2
4 4 4 filler-data filler-data-2
991 991 991 filler-data filler-data-2
992 992 992 filler-data filler-data-2
993 993 993 filler-data filler-data-2
994 994 994 filler-data filler-data-2
995 995 995 filler-data filler-data-2
996 996 996 filler-data filler-data-2
997 997 997 filler-data filler-data-2
998 998 998 filler-data filler-data-2
999 999 999 filler-data filler-data-2
1000 1000 1000 filler-data filler-data-2
11 11 11 filler-data filler-data-2
12 12 12 filler-data filler-data-2
13 13 13 filler-data filler-data-2
14 14 14 filler-data filler-data-2
50 50 50 filler-data filler-data-2
51 51 51 filler-data filler-data-2
52 52 52 filler-data filler-data-2
53 53 53 filler-data filler-data-2
54 54 54 filler-data filler-data-2
drop table t1;
mysql-test/t/index_merge_bdb.test
0 → 100644
View file @
24c18094
#
# 2-sweeps read Index_merge test
#
--
source
include
/
have_bdb
.
inc
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
pk
int
primary
key
,
key1
int
,
key2
int
,
filler
char
(
200
),
filler2
char
(
200
),
index
(
key1
),
index
(
key2
),
)
type
=
bdb
;
--
disable_query_log
let
$
1
=
1000
;
while
(
$
1
)
{
eval
insert
into
t1
values
(
$
1
,
$
1
,
$
1
,
'filler-data'
,
'filler-data-2'
);
dec
$
1
;
}
--
enable_query_log
select
*
from
t1
where
(
key1
>=
2
and
key1
<=
10
)
or
(
pk
>=
4
and
pk
<=
8
);
set
@
maxv
=
1000
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
key1
=
18
or
key1
=
60
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
key1
<
3
or
key1
>
@
maxv
-
11
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
(
key1
<
5
)
or
(
key1
>
10
and
key1
<
15
)
or
(
key1
>=
50
and
key1
<
55
)
or
(
key1
>
@
maxv
-
10
);
select
*
from
t1
where
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
key1
<
5
)
or
(
key1
>
@
maxv
-
10
);
drop
table
t1
;
mysql-test/t/index_merge_innodb2.test
0 → 100644
View file @
24c18094
#
# 2-sweeps read Index_merge test
#
--
source
include
/
have_innodb
.
inc
--
disable_warnings
drop
table
if
exists
t1
;
--
enable_warnings
create
table
t1
(
pk
int
primary
key
,
key1
int
,
key2
int
,
filler
char
(
200
),
filler2
char
(
200
),
index
(
key1
),
index
(
key2
),
)
type
=
innodb
;
--
disable_query_log
let
$
1
=
1000
;
while
(
$
1
)
{
eval
insert
into
t1
values
(
$
1
,
$
1
,
$
1
,
'filler-data'
,
'filler-data-2'
);
dec
$
1
;
}
--
enable_query_log
select
*
from
t1
where
(
key1
>=
2
and
key1
<=
10
)
or
(
pk
>=
4
and
pk
<=
8
);
set
@
maxv
=
1000
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
key1
=
18
or
key1
=
60
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
key1
<
3
or
key1
>
@
maxv
-
11
;
select
*
from
t1
where
(
pk
<
5
)
or
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
pk
>
@
maxv
-
10
)
or
(
key1
<
5
)
or
(
key1
>
10
and
key1
<
15
)
or
(
key1
>=
50
and
key1
<
55
)
or
(
key1
>
@
maxv
-
10
);
select
*
from
t1
where
(
pk
>
10
and
pk
<
15
)
or
(
pk
>=
50
and
pk
<
55
)
or
(
key1
<
5
)
or
(
key1
>
@
maxv
-
10
);
drop
table
t1
;
sql/filesort.cc
View file @
24c18094
...
...
@@ -87,9 +87,15 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
DBUG_PUSH
(
""
);
/* No DBUG here */
#endif
FILESORT_INFO
table_sort
;
bzero
(
&
table_sort
,
sizeof
(
FILESORT_INFO
));
/*
don't use table->sort in filesort as it is also used by
QUICK_INDEX_MERGE_SELECT. work with a copy of it and put it back at the
end when index_merge select has finished with it.
*/
memcpy
(
&
table_sort
,
&
table
->
sort
,
sizeof
(
FILESORT_INFO
));
table
->
sort
.
io_cache
=
NULL
;
outfile
=
table
->
sort
.
io_cache
;
outfile
=
table
_
sort
.
io_cache
;
my_b_clear
(
&
tempfile
);
my_b_clear
(
&
buffpek_pointers
);
buffpek
=
0
;
...
...
@@ -261,7 +267,6 @@ ha_rows filesort(THD *thd, TABLE *table, SORT_FIELD *sortorder, uint s_length,
DBUG_POP
();
/* Ok to DBUG */
#endif
memcpy
(
&
table
->
sort
,
&
table_sort
,
sizeof
(
FILESORT_INFO
));
table
->
sort
.
io_cache
=
outfile
;
DBUG_PRINT
(
"exit"
,(
"records: %ld"
,
records
));
DBUG_RETURN
(
error
?
HA_POS_ERROR
:
records
);
}
/* filesort */
...
...
@@ -445,7 +450,13 @@ static ha_rows find_all_keys(SORTPARAM *param, SQL_SELECT *select,
file
->
unlock_row
();
}
if
(
quick_select
)
{
/*
index_merge quick select uses table->sort when retrieving rows, so free
resoures it has allocated.
*/
end_read_record
(
&
read_record_info
);
}
else
{
(
void
)
file
->
extra
(
HA_EXTRA_NO_CACHE
);
/* End cacheing of records */
...
...
sql/ha_berkeley.h
View file @
24c18094
...
...
@@ -167,6 +167,7 @@ class ha_berkeley: public handler
longlong
get_auto_increment
();
void
print_error
(
int
error
,
myf
errflag
);
uint8
table_cache_type
()
{
return
HA_CACHE_TBL_TRANSACT
;
}
bool
primary_key_is_clustered_covering
()
{
return
true
;
}
};
extern
bool
berkeley_skip
,
berkeley_shared_data
;
...
...
sql/ha_innodb.cc
View file @
24c18094
...
...
@@ -2001,10 +2001,12 @@ build_template(
update field->query_id so that the formula
thd->query_id == field->query_id did not work. */
if
(
templ_type
==
ROW_MYSQL_REC_FIELDS
&&
!
(
fetch_all_in_key
&&
dict_index_contains_col_or_prefix
(
index
,
i
))
&&
thd
->
query_id
!=
field
->
query_id
)
{
ibool
index_contains_field
=
dict_index_contains_col_or_prefix
(
index
,
i
);
if
(
templ_type
==
ROW_MYSQL_REC_FIELDS
&&
((
prebuilt
->
read_just_key
&&
!
index_contains_field
)
||
(
!
(
fetch_all_in_key
&&
index_contains_field
)
&&
thd
->
query_id
!=
field
->
query_id
)))
{
/* This field is not needed in the query, skip it */
...
...
sql/ha_innodb.h
View file @
24c18094
...
...
@@ -187,6 +187,7 @@ class ha_innobase: public handler
void
init_table_handle_for_HANDLER
();
longlong
get_auto_increment
();
uint8
table_cache_type
()
{
return
HA_CACHE_TBL_ASKTRANSACT
;
}
bool
primary_key_is_clustered_covering
()
{
return
true
;
}
};
extern
bool
innodb_skip
;
...
...
sql/handler.h
View file @
24c18094
...
...
@@ -368,6 +368,13 @@ class handler :public Sql_alloc
*/
static
bool
caching_allowed
(
THD
*
thd
,
char
*
table_key
,
uint
key_length
,
uint8
cahe_type
);
/*
RETURN
true primary key (if there is one) is clustered key covering all fields
false otherwise
*/
virtual
bool
primary_key_is_clustered_covering
()
{
return
false
;
}
};
/* Some extern variables used with handlers */
...
...
sql/opt_range.cc
View file @
24c18094
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
24c18094
...
...
@@ -68,7 +68,7 @@ class QUICK_RANGE :public Sql_alloc {
/*
Quick select interface.
This class is parent for all QUICK_*_SELECT and FT_SELECT classes.
This class is
a
parent for all QUICK_*_SELECT and FT_SELECT classes.
*/
class
QUICK_SELECT_I
...
...
@@ -128,19 +128,29 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
SEL_ARG
*
key_tree
,
MEM_ROOT
*
alloc
);
friend
class
QUICK_SELECT_DESC
;
friend
class
QUICK_INDEX_MERGE_SELECT
;
DYNAMIC_ARRAY
ranges
;
/* ordered array of range ptrs */
QUICK_RANGE
**
cur_range
;
/* current element in ranges */
List
<
QUICK_RANGE
>
ranges
;
List_iterator
<
QUICK_RANGE
>
it
;
QUICK_RANGE
*
range
;
MEM_ROOT
alloc
;
KEY_PART
*
key_parts
;
int
cmp_next
(
QUICK_RANGE
*
range
);
int
cmp_prev
(
QUICK_RANGE
*
range
);
bool
row_in_ranges
();
public:
QUICK_RANGE_SELECT
(
THD
*
thd
,
TABLE
*
table
,
uint
index_arg
,
bool
no_alloc
=
0
,
MEM_ROOT
*
parent_alloc
=
NULL
);
~
QUICK_RANGE_SELECT
();
int
reset
(
void
)
{
next
=
0
;
it
.
rewind
();
return
0
;
}
int
reset
(
void
)
{
next
=
0
;
range
=
NULL
;
cur_range
=
NULL
;
return
0
;
}
int
init
();
int
get_next
();
bool
reverse_sorted
()
{
return
0
;
}
...
...
@@ -148,9 +158,60 @@ class QUICK_RANGE_SELECT : public QUICK_SELECT_I
int
get_type
()
{
return
QS_TYPE_RANGE
;
}
};
/*
Index merge quick select.
It is implemented as a container for several QUICK_RANGE_SELECTs.
QUICK_INDEX_MERGE_SELECT - index_merge acces method quick select.
QUICK_INDEX_MERGE_SELECT uses
* QUICK_RANGE_SELECTs to get rows
* Unique class to remove duplicate rows
INDEX MERGE OPTIMIZER
Current implementation doesn't detect all cases where index_merge could be
used, in particular:
* index_merge will never be used if range scan is possible (even if range
scan is more expensive)
* index_merge+'using index' is not supported (this the consequence of the
above restriction)
* If WHERE part contains complex nested AND and OR conditions, some ways to
retrieve rows using index_merge will not be considered. The choice of
read plan may depend on the order of conjuncts/disjuncts in WHERE part of
the query, see comments near SEL_IMERGE::or_sel_tree_with_checks and
imerge_list_or_list function for details.
* there is no "index_merge_ref" method (but index_merge on non-first table
in join is possible with 'range checked for each record').
See comments around SEL_IMERGE class and test_quick_select for more details.
ROW RETRIEVAL ALGORITHM
index_merge uses Unique class for duplicates removal. Index merge takes
advantage of clustered covering primary key (CCPK) if the table has one.
The algorithm is as follows:
prepare() //implemented in QUICK_INDEX_MERGE_SELECT::prepare_unique
{
activate 'index only';
while(retrieve next row for non-CCPK scan)
{
if (there is a CCPK scan and row will be retrieved by it)
skip this row;
else
put rowid into Unique;
}
deactivate 'index only';
}
fetch() //implemented as sequence of QUICK_INDEX_MERGE_SELECT::get_next calls
{
retrieve all rows from row pointers stored in Unique;
free Unique;
retrieve all rows for CCPK scan;
}
*/
class
QUICK_INDEX_MERGE_SELECT
:
public
QUICK_SELECT_I
...
...
@@ -175,8 +236,14 @@ class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
List_iterator_fast
<
QUICK_RANGE_SELECT
>
cur_quick_it
;
QUICK_RANGE_SELECT
*
cur_quick_select
;
/* last element in quick_selects list
.
*/
/* last element in quick_selects list */
QUICK_RANGE_SELECT
*
last_quick_select
;
/* quick select that uses Covering Clustered Primary Key (NULL if none) */
QUICK_RANGE_SELECT
*
pk_quick_select
;
/* true if this select is currently doing a CCPK scan */
bool
doing_pk_scan
;
Unique
*
unique
;
MEM_ROOT
alloc
;
...
...
@@ -184,6 +251,9 @@ class QUICK_INDEX_MERGE_SELECT : public QUICK_SELECT_I
THD
*
thd
;
int
prepare_unique
();
bool
reset_called
;
/* used to get rows collected in Unique */
READ_RECORD
read_record
;
};
class
QUICK_SELECT_DESC
:
public
QUICK_RANGE_SELECT
...
...
@@ -194,7 +264,6 @@ class QUICK_SELECT_DESC: public QUICK_RANGE_SELECT
bool
reverse_sorted
()
{
return
1
;
}
int
get_type
()
{
return
QS_TYPE_RANGE_DESC
;
}
private:
int
cmp_prev
(
QUICK_RANGE
*
range
);
bool
range_reads_after_key
(
QUICK_RANGE
*
range
);
#ifdef NOT_USED
bool
test_if_null_range
(
QUICK_RANGE
*
range
,
uint
used_key_parts
);
...
...
sql/records.cc
View file @
24c18094
...
...
@@ -97,8 +97,8 @@ void init_read_record(READ_RECORD *info,THD *thd, TABLE *table,
}
}
}
else
if
(
select
&&
select
->
quick
&&
(
select
->
quick
->
get_type
()
!=
QUICK_SELECT_I
::
QS_TYPE_INDEX_MERGE
))
else
if
(
select
&&
select
->
quick
)
//&&
(select->quick->get_type() != QUICK_SELECT_I::QS_TYPE_INDEX_MERGE))
{
DBUG_PRINT
(
"info"
,(
"using rr_quick"
));
info
->
read_record
=
rr_quick
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment