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
7711999d
Commit
7711999d
authored
Jun 25, 2014
by
Sergei Petrunia
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MDEV-406: ANALYZE $stmt: add support for BNL join buffering
parent
c3cfb691
Changes
8
Hide whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
122 additions
and
26 deletions
+122
-26
mysql-test/r/analyze_stmt.result
mysql-test/r/analyze_stmt.result
+37
-0
mysql-test/t/analyze_stmt.test
mysql-test/t/analyze_stmt.test
+25
-0
sql/sql_explain.cc
sql/sql_explain.cc
+4
-6
sql/sql_explain.h
sql/sql_explain.h
+21
-5
sql/sql_join_cache.cc
sql/sql_join_cache.cc
+28
-10
sql/sql_join_cache.h
sql/sql_join_cache.h
+4
-4
sql/sql_select.cc
sql/sql_select.cc
+2
-1
sql/sql_select.h
sql/sql_select.h
+1
-0
No files found.
mysql-test/r/analyze_stmt.result
View file @
7711999d
...
@@ -79,4 +79,41 @@ analyze select a, a in (select t0.b from t0 where t0.b+1=t1.b+1) from t1 where t
...
@@ -79,4 +79,41 @@ analyze select a, a in (select t0.b from t0 where t0.b+1=t1.b+1) from t1 where t
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 3 100.00 0.00 Using where
1 PRIMARY t1 ALL NULL NULL NULL NULL 3 3 100.00 0.00 Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 NULL 100.00 NULL Using where
2 DEPENDENT SUBQUERY t0 ALL NULL NULL NULL NULL 10 NULL 100.00 NULL Using where
drop table t0, t1;
#
# Tests for join buffering
#
create table t0 (a int, b int);
insert into t0 values
(0,0),(1,1),(2,2),(3,3),(4,4),(5,5),(6,6),(7,7),(8,8),(9,9);
create table t1 like t0;
insert into t1 select * from t0;
explain select * from t0, t1 where t0.a<5 and t1.a<5;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
# These should have filtered=50
analyze select * from t0, t1 where t0.a<5 and t1.a<5;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 10 100.00 50.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 50.00 Using where; Using join buffer (flat, BNL join)
explain select * from t0, t1 where t0.a<5 and t1.b=t0.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
# Now, t1 should have filtered=10
analyze select * from t0, t1 where t0.a<5 and t1.b=t0.b;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 10 100.00 50.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 10.00 Using where; Using join buffer (flat, BNL join)
explain select * from t0, t1 where t0.a<5 and t1.a<5 and t1.b=t0.b;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 Using where; Using join buffer (flat, BNL join)
# Now, t1 should have filtered=10
analyze select * from t0, t1 where t0.a<5 and t1.a<5 and t1.b=t0.b;
id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
1 SIMPLE t0 ALL NULL NULL NULL NULL 10 10 100.00 50.00 Using where
1 SIMPLE t1 ALL NULL NULL NULL NULL 10 10 100.00 10.00 Using where; Using join buffer (flat, BNL join)
drop table t0,t1;
drop table t0,t1;
# TODO: Check what is counted for "range checked for each record".
mysql-test/t/analyze_stmt.test
View file @
7711999d
...
@@ -61,5 +61,30 @@ analyze select a, a in (select t0.b from t0 where t0.b+1=t1.b+1) from t1;
...
@@ -61,5 +61,30 @@ analyze select a, a in (select t0.b from t0 where t0.b+1=t1.b+1) from t1;
--
echo
# Try a subquery that is never executed
--
echo
# Try a subquery that is never executed
analyze
select
a
,
a
in
(
select
t0
.
b
from
t0
where
t0
.
b
+
1
=
t1
.
b
+
1
)
from
t1
where
t1
.
a
>
5
;
analyze
select
a
,
a
in
(
select
t0
.
b
from
t0
where
t0
.
b
+
1
=
t1
.
b
+
1
)
from
t1
where
t1
.
a
>
5
;
drop
table
t0
,
t1
;
--
echo
#
--
echo
# Tests for join buffering
--
echo
#
create
table
t0
(
a
int
,
b
int
);
insert
into
t0
values
(
0
,
0
),(
1
,
1
),(
2
,
2
),(
3
,
3
),(
4
,
4
),(
5
,
5
),(
6
,
6
),(
7
,
7
),(
8
,
8
),(
9
,
9
);
create
table
t1
like
t0
;
insert
into
t1
select
*
from
t0
;
explain
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
a
<
5
;
--
echo
# These should have filtered=50
analyze
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
a
<
5
;
explain
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
b
=
t0
.
b
;
--
echo
# Now, t1 should have filtered=10
analyze
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
b
=
t0
.
b
;
explain
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
a
<
5
and
t1
.
b
=
t0
.
b
;
--
echo
# Now, t1 should have filtered=10
analyze
select
*
from
t0
,
t1
where
t0
.
a
<
5
and
t1
.
a
<
5
and
t1
.
b
=
t0
.
b
;
drop
table
t0
,
t1
;
drop
table
t0
,
t1
;
--
echo
# TODO: Check what is counted for "range checked for each record".
sql/sql_explain.cc
View file @
7711999d
...
@@ -585,12 +585,10 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
...
@@ -585,12 +585,10 @@ int Explain_table_access::print_explain(select_result_sink *output, uint8 explai
}
}
else
else
{
{
double
r_filtered
;
double
r_filtered
=
tracker
.
get_filtered_after_where
();
if
(
tracker
.
r_rows
>
0
)
if
(
bka_type
.
is_using_jbuf
())
r_filtered
=
100.0
*
(
double
)
tracker
.
r_rows_after_table_cond
/
tracker
.
r_rows
;
r_filtered
*=
jbuf_tracker
.
get_filtered_after_where
();
else
item_list
.
push_back
(
new
Item_float
(
r_filtered
*
100.0
,
2
));
r_filtered
=
100.0
;
item_list
.
push_back
(
new
Item_float
(
r_filtered
,
2
));
}
}
}
}
...
...
sql/sql_explain.h
View file @
7711999d
...
@@ -19,13 +19,13 @@ class Table_access_tracker
...
@@ -19,13 +19,13 @@ class Table_access_tracker
{
{
public:
public:
Table_access_tracker
()
:
Table_access_tracker
()
:
r_scans
(
0
),
r_rows
(
0
),
r_rows_after_table_cond
(
0
),
r_scans
(
0
),
r_rows
(
0
),
/*r_rows_after_table_cond(0),*/
r_rows_after_where
(
0
)
r_rows_after_where
(
0
)
{}
{}
ha_rows
r_scans
;
/* How many scans were ran on this join_tab */
ha_rows
r_scans
;
/* How many scans were ran on this join_tab */
ha_rows
r_rows
;
/* How many rows we've got after that */
ha_rows
r_rows
;
/* How many rows we've got after that */
ha_rows
r_rows_after_table_cond
;
/* Rows after applying the table condition */
//
ha_rows r_rows_after_table_cond; /* Rows after applying the table condition */
ha_rows
r_rows_after_where
;
/* Rows after applying attached part of WHERE */
ha_rows
r_rows_after_where
;
/* Rows after applying attached part of WHERE */
bool
has_scans
()
{
return
(
r_scans
!=
0
);
}
bool
has_scans
()
{
return
(
r_scans
!=
0
);
}
...
@@ -33,6 +33,17 @@ class Table_access_tracker
...
@@ -33,6 +33,17 @@ class Table_access_tracker
{
{
return
r_scans
?
(
ha_rows
)
rint
((
double
)
r_rows
/
r_scans
)
:
0
;
return
r_scans
?
(
ha_rows
)
rint
((
double
)
r_rows
/
r_scans
)
:
0
;
}
}
double
get_filtered_after_where
()
{
double
r_filtered
;
if
(
r_rows
>
0
)
r_filtered
=
(
double
)
r_rows_after_where
/
r_rows
;
else
r_filtered
=
1.0
;
return
r_filtered
;
}
};
};
...
@@ -371,13 +382,17 @@ enum explain_extra_tag
...
@@ -371,13 +382,17 @@ enum explain_extra_tag
};
};
typedef
struct
st_explain_bka_type
class
EXPLAIN_BKA_TYPE
{
{
public:
EXPLAIN_BKA_TYPE
()
:
join_alg
(
NULL
)
{}
bool
incremental
;
bool
incremental
;
const
char
*
join_alg
;
const
char
*
join_alg
;
StringBuffer
<
64
>
mrr_type
;
StringBuffer
<
64
>
mrr_type
;
}
EXPLAIN_BKA_TYPE
;
bool
is_using_jbuf
()
{
return
(
join_alg
!=
NULL
);
}
};
/*
/*
...
@@ -517,6 +532,7 @@ class Explain_table_access : public Sql_alloc
...
@@ -517,6 +532,7 @@ class Explain_table_access : public Sql_alloc
/* ANALYZE members*/
/* ANALYZE members*/
Table_access_tracker
tracker
;
Table_access_tracker
tracker
;
Table_access_tracker
jbuf_tracker
;
private:
private:
void
append_tag_name
(
String
*
str
,
enum
explain_extra_tag
tag
);
void
append_tag_name
(
String
*
str
,
enum
explain_extra_tag
tag
);
...
...
sql/sql_join_cache.cc
View file @
7711999d
...
@@ -2254,7 +2254,7 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
...
@@ -2254,7 +2254,7 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
*/
*/
goto
finish
;
goto
finish
;
}
}
while
(
!
(
error
=
join_tab_scan
->
next
()))
while
(
!
(
error
=
join_tab_scan
->
next
()))
{
{
if
(
join
->
thd
->
check_killed
())
if
(
join
->
thd
->
check_killed
())
...
@@ -2271,11 +2271,13 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
...
@@ -2271,11 +2271,13 @@ enum_nested_loop_state JOIN_CACHE::join_matching_records(bool skip_last)
/* Prepare to read matching candidates from the join buffer */
/* Prepare to read matching candidates from the join buffer */
if
(
prepare_look_for_matches
(
skip_last
))
if
(
prepare_look_for_matches
(
skip_last
))
continue
;
continue
;
join_tab
->
jbuf_tracker
->
r_scans
++
;
uchar
*
rec_ptr
;
uchar
*
rec_ptr
;
/* Read each possible candidate from the buffer and look for matches */
/* Read each possible candidate from the buffer and look for matches */
while
((
rec_ptr
=
get_next_candidate_for_match
()))
while
((
rec_ptr
=
get_next_candidate_for_match
()))
{
{
join_tab
->
jbuf_tracker
->
r_rows
++
;
/*
/*
If only the first match is needed, and, it has been already found for
If only the first match is needed, and, it has been already found for
the next record read from the join buffer, then the record is skipped.
the next record read from the join buffer, then the record is skipped.
...
@@ -2445,6 +2447,8 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
...
@@ -2445,6 +2447,8 @@ inline bool JOIN_CACHE::check_match(uchar *rec_ptr)
if
(
join_tab
->
select
&&
join_tab
->
select
->
skip_record
(
join
->
thd
)
<=
0
)
if
(
join_tab
->
select
&&
join_tab
->
select
->
skip_record
(
join
->
thd
)
<=
0
)
DBUG_RETURN
(
FALSE
);
DBUG_RETURN
(
FALSE
);
join_tab
->
jbuf_tracker
->
r_rows_after_where
++
;
if
(
!
join_tab
->
is_last_inner_table
())
if
(
!
join_tab
->
is_last_inner_table
())
DBUG_RETURN
(
TRUE
);
DBUG_RETURN
(
TRUE
);
...
@@ -2568,7 +2572,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
...
@@ -2568,7 +2572,7 @@ enum_nested_loop_state JOIN_CACHE::join_null_complements(bool skip_last)
none
none
*/
*/
void
JOIN_CACHE
::
save_explain_data
(
struct
st_explain_bka_type
*
explain
)
void
JOIN_CACHE
::
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
)
{
{
explain
->
incremental
=
MY_TEST
(
prev_cache
);
explain
->
incremental
=
MY_TEST
(
prev_cache
);
...
@@ -2613,14 +2617,14 @@ static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
...
@@ -2613,14 +2617,14 @@ static void add_mrr_explain_info(String *str, uint mrr_mode, handler *file)
}
}
}
}
void
JOIN_CACHE_BKA
::
save_explain_data
(
struct
st_explain_bka_type
*
explain
)
void
JOIN_CACHE_BKA
::
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
)
{
{
JOIN_CACHE
::
save_explain_data
(
explain
);
JOIN_CACHE
::
save_explain_data
(
explain
);
add_mrr_explain_info
(
&
explain
->
mrr_type
,
mrr_mode
,
join_tab
->
table
->
file
);
add_mrr_explain_info
(
&
explain
->
mrr_type
,
mrr_mode
,
join_tab
->
table
->
file
);
}
}
void
JOIN_CACHE_BKAH
::
save_explain_data
(
struct
st_explain_bka_type
*
explain
)
void
JOIN_CACHE_BKAH
::
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
)
{
{
JOIN_CACHE
::
save_explain_data
(
explain
);
JOIN_CACHE
::
save_explain_data
(
explain
);
add_mrr_explain_info
(
&
explain
->
mrr_type
,
mrr_mode
,
join_tab
->
table
->
file
);
add_mrr_explain_info
(
&
explain
->
mrr_type
,
mrr_mode
,
join_tab
->
table
->
file
);
...
@@ -3326,6 +3330,7 @@ int JOIN_TAB_SCAN::open()
...
@@ -3326,6 +3330,7 @@ int JOIN_TAB_SCAN::open()
{
{
save_or_restore_used_tabs
(
join_tab
,
FALSE
);
save_or_restore_used_tabs
(
join_tab
,
FALSE
);
is_first_record
=
TRUE
;
is_first_record
=
TRUE
;
join_tab
->
tracker
->
r_scans
++
;
return
join_init_read_record
(
join_tab
);
return
join_init_read_record
(
join_tab
);
}
}
...
@@ -3364,8 +3369,14 @@ int JOIN_TAB_SCAN::next()
...
@@ -3364,8 +3369,14 @@ int JOIN_TAB_SCAN::next()
is_first_record
=
FALSE
;
is_first_record
=
FALSE
;
else
else
err
=
info
->
read_record
(
info
);
err
=
info
->
read_record
(
info
);
if
(
!
err
&&
table
->
vfield
)
update_virtual_fields
(
thd
,
table
);
if
(
!
err
)
{
join_tab
->
tracker
->
r_rows
++
;
if
(
table
->
vfield
)
update_virtual_fields
(
thd
,
table
);
}
while
(
!
err
&&
select
&&
(
skip_rc
=
select
->
skip_record
(
thd
))
<=
0
)
while
(
!
err
&&
select
&&
(
skip_rc
=
select
->
skip_record
(
thd
))
<=
0
)
{
{
if
(
thd
->
check_killed
()
||
skip_rc
<
0
)
if
(
thd
->
check_killed
()
||
skip_rc
<
0
)
...
@@ -3375,9 +3386,16 @@ int JOIN_TAB_SCAN::next()
...
@@ -3375,9 +3386,16 @@ int JOIN_TAB_SCAN::next()
meet the condition pushed to the table join_tab.
meet the condition pushed to the table join_tab.
*/
*/
err
=
info
->
read_record
(
info
);
err
=
info
->
read_record
(
info
);
if
(
!
err
&&
table
->
vfield
)
if
(
!
err
)
update_virtual_fields
(
thd
,
table
);
{
}
join_tab
->
tracker
->
r_rows
++
;
if
(
table
->
vfield
)
update_virtual_fields
(
thd
,
table
);
}
}
if
(
!
err
)
join_tab
->
tracker
->
r_rows_after_where
++
;
return
err
;
return
err
;
}
}
...
...
sql/sql_join_cache.h
View file @
7711999d
...
@@ -63,7 +63,7 @@ typedef struct st_cache_field {
...
@@ -63,7 +63,7 @@ typedef struct st_cache_field {
class
JOIN_TAB_SCAN
;
class
JOIN_TAB_SCAN
;
struct
st_explain_bka_type
;
class
EXPLAIN_BKA_TYPE
;
/*
/*
JOIN_CACHE is the base class to support the implementations of
JOIN_CACHE is the base class to support the implementations of
...
@@ -659,7 +659,7 @@ class JOIN_CACHE :public Sql_alloc
...
@@ -659,7 +659,7 @@ class JOIN_CACHE :public Sql_alloc
enum_nested_loop_state
join_records
(
bool
skip_last
);
enum_nested_loop_state
join_records
(
bool
skip_last
);
/* Add a comment on the join algorithm employed by the join cache */
/* Add a comment on the join algorithm employed by the join cache */
virtual
void
save_explain_data
(
struct
st_explain_bka_type
*
explain
);
virtual
void
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
);
THD
*
thd
();
THD
*
thd
();
...
@@ -1337,7 +1337,7 @@ class JOIN_CACHE_BKA :public JOIN_CACHE
...
@@ -1337,7 +1337,7 @@ class JOIN_CACHE_BKA :public JOIN_CACHE
/* Check index condition of the joined table for a record from BKA cache */
/* Check index condition of the joined table for a record from BKA cache */
bool
skip_index_tuple
(
range_id_t
range_info
);
bool
skip_index_tuple
(
range_id_t
range_info
);
void
save_explain_data
(
struct
st_explain_bka_type
*
explain
);
void
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
);
};
};
...
@@ -1428,5 +1428,5 @@ class JOIN_CACHE_BKAH :public JOIN_CACHE_BNLH
...
@@ -1428,5 +1428,5 @@ class JOIN_CACHE_BKAH :public JOIN_CACHE_BNLH
/* Check index condition of the joined table for a record from BKAH cache */
/* Check index condition of the joined table for a record from BKAH cache */
bool
skip_index_tuple
(
range_id_t
range_info
);
bool
skip_index_tuple
(
range_id_t
range_info
);
void
save_explain_data
(
struct
st_explain_bka_type
*
explain
);
void
save_explain_data
(
EXPLAIN_BKA_TYPE
*
explain
);
};
};
sql/sql_select.cc
View file @
7711999d
...
@@ -17731,7 +17731,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
...
@@ -17731,7 +17731,7 @@ evaluate_join_record(JOIN *join, JOIN_TAB *join_tab,
There is no select condition or the attached pushed down
There is no select condition or the attached pushed down
condition is true => a match is found.
condition is true => a match is found.
*/
*/
join_tab
->
tracker
->
r_rows_after_
table_cond
++
;
join_tab
->
tracker
->
r_rows_after_
where
++
;
bool
found
=
1
;
bool
found
=
1
;
while
(
join_tab
->
first_unmatched
&&
found
)
while
(
join_tab
->
first_unmatched
&&
found
)
{
{
...
@@ -23308,6 +23308,7 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab
...
@@ -23308,6 +23308,7 @@ void JOIN_TAB::save_explain_data(Explain_table_access *eta, table_map prefix_tab
eta
->
quick_info
=
NULL
;
eta
->
quick_info
=
NULL
;
tab
->
tracker
=
&
eta
->
tracker
;
tab
->
tracker
=
&
eta
->
tracker
;
tab
->
jbuf_tracker
=
&
eta
->
jbuf_tracker
;
/* id */
/* id */
if
(
tab
->
bush_root_tab
)
if
(
tab
->
bush_root_tab
)
...
...
sql/sql_select.h
View file @
7711999d
...
@@ -252,6 +252,7 @@ typedef struct st_join_table {
...
@@ -252,6 +252,7 @@ typedef struct st_join_table {
enum
explain_extra_tag
info
;
enum
explain_extra_tag
info
;
Table_access_tracker
*
tracker
;
Table_access_tracker
*
tracker
;
Table_access_tracker
*
jbuf_tracker
;
/*
/*
Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
Bitmap of TAB_INFO_* bits that encodes special line for EXPLAIN 'Extra'
column, or 0 if there is no info.
column, or 0 if there is no info.
...
...
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