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
fdb77fd3
Commit
fdb77fd3
authored
Jan 09, 2020
by
Varun Gupta
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fix to address performance regression of ORDER BY with limit queries
parent
5a9e6261
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
52 additions
and
31 deletions
+52
-31
sql/opt_subselect.cc
sql/opt_subselect.cc
+4
-4
sql/sql_select.cc
sql/sql_select.cc
+43
-23
sql/sql_select.h
sql/sql_select.h
+4
-3
sql/sql_sort_nest.cc
sql/sql_sort_nest.cc
+1
-1
No files found.
sql/opt_subselect.cc
View file @
fdb77fd3
...
...
@@ -3140,7 +3140,7 @@ bool Sj_materialization_picker::check_qep(JOIN *join,
best_access_path
(
join
,
join
->
positions
[
i
].
table
,
rem_tables
,
join
->
positions
,
i
,
disable_jbuf
,
prefix_rec_count
,
&
curpos
,
&
dummy
,
0
,
FALSE
);
0
,
FALSE
,
DBL_MAX
);
prefix_rec_count
=
COST_MULT
(
prefix_rec_count
,
curpos
.
records_read
);
prefix_cost
=
COST_ADD
(
prefix_cost
,
curpos
.
read_time
);
prefix_cost
=
COST_ADD
(
prefix_cost
,
...
...
@@ -3839,7 +3839,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
best_access_path
(
join
,
join
->
best_positions
[
i
].
table
,
rem_tables
,
join
->
best_positions
,
i
,
FALSE
,
prefix_rec_count
,
join
->
best_positions
+
i
,
&
dummy
,
0
,
FALSE
);
join
->
best_positions
+
i
,
&
dummy
,
0
,
FALSE
,
DBL_MAX
);
join
->
best_positions
[
i
].
sort_nest_operation_here
=
save_sort_nest_op
;
prefix_rec_count
*=
join
->
best_positions
[
i
].
records_read
;
rem_tables
&=
~
join
->
best_positions
[
i
].
table
->
table
->
map
;
...
...
@@ -3882,7 +3882,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
rem_tables
,
join
->
best_positions
,
idx
,
TRUE
/* no jbuf */
,
record_count
,
join
->
best_positions
+
idx
,
&
dummy
,
0
,
FALSE
);
0
,
FALSE
,
DBL_MAX
);
}
record_count
*=
join
->
best_positions
[
idx
].
records_read
;
rem_tables
&=
~
join
->
best_positions
[
idx
].
table
->
table
->
map
;
...
...
@@ -3922,7 +3922,7 @@ void fix_semijoin_strategies_for_picked_join_order(JOIN *join)
rem_tables
,
join
->
best_positions
,
idx
,
TRUE
/* no jbuf */
,
record_count
,
join
->
best_positions
+
idx
,
&
loose_scan_pos
,
0
,
FALSE
);
&
loose_scan_pos
,
0
,
FALSE
,
DBL_MAX
);
if
(
idx
==
first
)
{
join
->
best_positions
[
idx
]
=
loose_scan_pos
;
...
...
sql/sql_select.cc
View file @
fdb77fd3
...
...
@@ -119,7 +119,8 @@ static bool best_extension_by_limited_search(JOIN *join,
uint
use_cond_selectivity
,
table_map
sort_nest_tables
,
bool
nest_created
,
bool
limit_applied_to_nest
);
bool
limit_applied_to_nest
,
double
sort_nest_records
);
static
uint
determine_search_depth
(
JOIN
*
join
);
C_MODE_START
static
int
join_tab_cmp
(
const
void
*
dummy
,
const
void
*
ptr1
,
const
void
*
ptr2
);
...
...
@@ -7294,7 +7295,8 @@ best_access_path(JOIN *join,
double
record_count
,
POSITION
*
pos
,
POSITION
*
loose_scan_pos
,
table_map
sort_nest_tables
,
bool
nest_created
)
table_map
sort_nest_tables
,
bool
nest_created
,
double
sort_nest_records
)
{
THD
*
thd
=
join
->
thd
;
uint
use_cond_selectivity
=
thd
->
variables
.
optimizer_use_condition_selectivity
;
...
...
@@ -7415,9 +7417,9 @@ best_access_path(JOIN *join,
double
tmp2
=
prev_record_reads
(
join_positions
,
idx
,
(
found_ref
|
keyuse
->
used_tables
),
sort_nest_tables
,
nest_created
?
join
->
fraction_output_for_nest
:
1.0
);
nest_created
,
nest_created
?
sort_nest_records
:
DBL_MAX
);
if
(
tmp2
<
best_prev_record_reads
)
{
best_part_found_ref
=
keyuse
->
used_tables
&
~
join
->
const_table_map
;
...
...
@@ -7459,9 +7461,8 @@ best_access_path(JOIN *join,
but 1.0 would be probably safer
*/
tmp
=
prev_record_reads
(
join_positions
,
idx
,
found_ref
,
sort_nest_tables
,
nest_created
?
join
->
fraction_output_for_nest
:
1.0
);
sort_nest_tables
,
nest_created
,
nest_created
?
sort_nest_records
:
DBL_MAX
);
records
=
1.0
;
type
=
JT_FT
;
trace_access_idx
.
add
(
"access_type"
,
join_type_str
[
type
])
...
...
@@ -7491,9 +7492,9 @@ best_access_path(JOIN *join,
trace_access_idx
.
add
(
"access_type"
,
join_type_str
[
type
])
.
add
(
"index"
,
keyinfo
->
name
);
tmp
=
prev_record_reads
(
join_positions
,
idx
,
found_ref
,
sort_nest_tables
,
sort_nest_tables
,
nest_created
,
nest_created
?
join
->
fraction_output_for_nest
:
1.0
);
sort_nest_records
:
DBL_MAX
);
records
=
1.0
;
}
else
...
...
@@ -8147,7 +8148,6 @@ best_access_path(JOIN *join,
join
->
sort_by_table
=
(
TABLE
*
)
1
;
// Must use temporary table
}
trace_access_scan
.
end
();
trace_paths
.
end
();
/*
Use the estimate of rows read for a table for range/table scan
...
...
@@ -8222,6 +8222,8 @@ best_access_path(JOIN *join,
if
(
unlikely
(
thd
->
trace_started
()))
print_best_access_for_table
(
thd
,
pos
,
best_type
);
trace_paths
.
end
();
DBUG_VOID_RETURN
;
}
...
...
@@ -8717,7 +8719,7 @@ optimize_straight_join(JOIN *join, table_map join_tables)
best_access_path
(
join
,
s
,
join_tables
,
join
->
positions
,
idx
,
disable_jbuf
,
record_count
,
position
,
&
loose_scan_pos
,
0
,
FALSE
);
0
,
FALSE
,
DBL_MAX
);
/* compute the cost of the new plan extended with 's' */
record_count
=
COST_MULT
(
record_count
,
position
->
records_read
);
...
...
@@ -8873,7 +8875,7 @@ greedy_search(JOIN *join,
prune_level
),
use_cond_selectivity
,
sort_nest_tables
,
FALSE
,
FALSE
))
FALSE
,
DBL_MAX
))
DBUG_RETURN
(
TRUE
);
/*
'best_read < DBL_MAX' means that optimizer managed to find
...
...
@@ -9619,7 +9621,8 @@ best_extension_by_limited_search(JOIN *join,
uint
use_cond_selectivity
,
table_map
sort_nest_tables
,
bool
nest_created
,
bool
limit_applied_to_nest
)
bool
limit_applied_to_nest
,
double
sort_nest_records
)
{
DBUG_ENTER
(
"best_extension_by_limited_search"
);
...
...
@@ -9652,6 +9655,7 @@ best_extension_by_limited_search(JOIN *join,
double
original_record_count
=
record_count
;
record_count
=
COST_MULT
(
record_count
,
join
->
fraction_output_for_nest
);
limit_applied_to_nest
=
TRUE
;
sort_nest_records
=
record_count
;
if
(
unlikely
(
thd
->
trace_started
()))
{
...
...
@@ -9706,7 +9710,7 @@ best_extension_by_limited_search(JOIN *join,
POSITION
loose_scan_pos
;
best_access_path
(
join
,
s
,
remaining_tables
,
join
->
positions
,
idx
,
disable_jbuf
,
record_count
,
position
,
&
loose_scan_pos
,
sort_nest_tables
,
nest_created
);
sort_nest_tables
,
nest_created
,
sort_nest_records
);
/*
sort_nest_operation_here is set to TRUE here in the special case
...
...
@@ -9810,7 +9814,10 @@ best_extension_by_limited_search(JOIN *join,
if
(
join
->
is_index_with_ordering_allowed
(
idx
)
&&
s
->
check_if_index_satisfies_ordering
(
index_used
))
{
limit_applied_to_nest
=
TRUE
;
sort_nest_records
=
partial_join_cardinality
;
}
if
(
!
nest_created
&&
(
join
->
prefix_resolves_ordering
||
...
...
@@ -9839,7 +9846,8 @@ best_extension_by_limited_search(JOIN *join,
prune_level
,
use_cond_selectivity
,
sort_nest_tables
|
real_table_bit
,
TRUE
,
limit_applied_to_nest
))
TRUE
,
limit_applied_to_nest
,
sort_nest_records
))
DBUG_RETURN
(
TRUE
);
if
(
!
(
join
->
is_index_with_ordering_allowed
(
idx
)
&&
s
->
check_if_index_satisfies_ordering
(
index_used
)))
...
...
@@ -9857,8 +9865,9 @@ best_extension_by_limited_search(JOIN *join,
use_cond_selectivity
,
nest_created
?
sort_nest_tables
:
sort_nest_tables
|
real_table_bit
,
nest_created
,
limit_applied_to_nest
))
nest_created
||
limit_applied_to_nest
,
limit_applied_to_nest
,
sort_nest_records
))
DBUG_RETURN
(
TRUE
);
trace_rest
.
end
();
...
...
@@ -9866,6 +9875,7 @@ best_extension_by_limited_search(JOIN *join,
{
limit_applied_to_nest
=
FALSE
;
join
->
positions
[
idx
].
sort_nest_operation_here
=
FALSE
;
sort_nest_records
=
DBL_MAX
;
}
swap_variables
(
JOIN_TAB
*
,
join
->
best_ref
[
idx
],
*
pos
);
}
...
...
@@ -10236,8 +10246,8 @@ cache_record_length_for_nest(JOIN *join,uint idx)
double
prev_record_reads
(
const
POSITION
*
positions
,
uint
idx
,
table_map
found_ref
,
table_map
sort_nest_tables
,
double
fraction_output_for_nest
)
table_map
sort_nest_tables
,
bool
nest_created
,
double
sort_nest_records
)
{
double
found
=
1.0
;
const
POSITION
*
pos_end
=
positions
-
1
;
...
...
@@ -10247,8 +10257,11 @@ prev_record_reads(const POSITION *positions, uint idx, table_map found_ref,
if
(
pos
->
table
->
table
->
map
&
found_ref
)
{
found_ref
|=
pos
->
ref_depend_map
;
if
(
pos
->
table
->
table
->
map
&
sort_nest_tables
)
if
(
nest_created
&&
pos
->
table
->
table
->
map
&
sort_nest_tables
)
{
apply_limit
=
TRUE
;
break
;
}
/*
For the case of "t1 LEFT JOIN t2 ON ..." where t2 is a const table
with no matching row we will get position[t2].records_read==0.
...
...
@@ -10272,8 +10285,15 @@ prev_record_reads(const POSITION *positions, uint idx, table_map found_ref,
}
}
}
/*
This needs to be done only once if the nest is created because we
would be referring to the context post sorting.
*/
if
(
apply_limit
)
found
=
COST_MULT
(
found
,
fraction_output_for_nest
);
{
DBUG_ASSERT
(
sort_nest_records
!=
DBL_MAX
);
found
=
COST_MULT
(
found
,
sort_nest_records
);
}
return
found
;
}
...
...
@@ -17351,7 +17371,7 @@ void optimize_wo_join_buffering(JOIN *join, uint first_tab, uint last_tab,
join
->
positions
,
i
,
TRUE
,
rec_count
,
&
pos
,
&
loose_scan_pos
,
0
,
FALSE
);
0
,
FALSE
,
DBL_MAX
);
}
else
pos
=
join
->
positions
[
i
];
...
...
sql/sql_select.h
View file @
fdb77fd3
...
...
@@ -881,7 +881,7 @@ class LooseScan_picker : public Semi_join_strategy_picker
struct
st_position
*
pos
,
struct
st_position
*
loose_scan_pos
,
table_map
sort_nest_tables
,
bool
nest_created
);
bool
nest_created
,
double
sort_nest_records
);
friend
bool
get_best_combination
(
JOIN
*
join
);
friend
int
setup_semijoin_loosescan
(
JOIN
*
join
);
friend
void
fix_semijoin_strategies_for_picked_join_order
(
JOIN
*
join
);
...
...
@@ -2291,7 +2291,8 @@ void best_access_path(JOIN *join, JOIN_TAB *s,
const
POSITION
*
join_positions
,
uint
idx
,
bool
disable_jbuf
,
double
record_count
,
POSITION
*
pos
,
POSITION
*
loose_scan_pos
,
table_map
sort_nest_tables
,
bool
nest_created
);
table_map
sort_nest_tables
,
bool
nest_created
,
double
sort_nest_records
);
bool
cp_buffer_from_ref
(
THD
*
thd
,
TABLE
*
table
,
TABLE_REF
*
ref
);
bool
error_if_full_join
(
JOIN
*
join
);
int
report_error
(
TABLE
*
table
,
int
error
);
...
...
@@ -2672,7 +2673,7 @@ bool open_tmp_table(TABLE *table);
void
setup_tmp_table_column_bitmaps
(
TABLE
*
table
,
uchar
*
bitmaps
);
double
prev_record_reads
(
const
POSITION
*
positions
,
uint
idx
,
table_map
found_ref
,
table_map
sort_nest_tables
,
double
fraction_output_for_nest
);
bool
nest_created
,
double
sort_nest_records
);
void
fix_list_after_tbl_changes
(
SELECT_LEX
*
new_parent
,
List
<
TABLE_LIST
>
*
tlist
);
double
get_tmp_table_lookup_cost
(
THD
*
thd
,
double
row_count
,
ulong
row_size
);
...
...
sql/sql_sort_nest.cc
View file @
fdb77fd3
...
...
@@ -1039,7 +1039,7 @@ int get_best_index_for_order_by_limit(JOIN_TAB *tab,
double
save_read_time
=
*
read_time
;
double
save_records
=
*
records
;
double
est_records
=
*
records
;
double
fanout
=
MY_MAX
(
1.0
,
cardinality
/
est_records
)
;
double
fanout
=
cardinality
/
est_records
;
int
best_index
=-
1
;
trace_index_for_ordering
.
add
(
"rows_estimation"
,
est_records
);
Json_writer_array
considered_indexes
(
thd
,
"considered_indexes"
);
...
...
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