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
eb437bbd
Commit
eb437bbd
authored
Dec 09, 2003
by
unknown
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Two-sweeps read index_merge plus several small index_merge fixes and improvements
parent
e98a211f
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 @
eb437bbd
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 @
eb437bbd
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 @
eb437bbd
#
# 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 @
eb437bbd
#
# 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 @
eb437bbd
...
...
@@ -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 @
eb437bbd
...
...
@@ -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 @
eb437bbd
...
...
@@ -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 @
eb437bbd
...
...
@@ -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 @
eb437bbd
...
...
@@ -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 @
eb437bbd
This diff is collapsed.
Click to expand it.
sql/opt_range.h
View file @
eb437bbd
...
...
@@ -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 @
eb437bbd
...
...
@@ -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