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
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
mariadb
Commits
b77e3dc9
Commit
b77e3dc9
authored
Mar 22, 2011
by
Sergey Petrunya
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
MWL#90: Address review feedback part #5
parent
809a8052
Changes
5
Hide whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
98 additions
and
132 deletions
+98
-132
sql/item_subselect.cc
sql/item_subselect.cc
+5
-5
sql/item_subselect.h
sql/item_subselect.h
+54
-59
sql/opt_subselect.cc
sql/opt_subselect.cc
+4
-7
sql/sql_join_cache.cc
sql/sql_join_cache.cc
+9
-3
sql/sql_select.cc
sql/sql_select.cc
+26
-58
No files found.
sql/item_subselect.cc
View file @
b77e3dc9
...
...
@@ -33,11 +33,11 @@
Item_subselect
::
Item_subselect
()
:
Item_result_field
(),
value_assigned
(
0
),
thd
(
0
),
substitution
(
0
),
expr_cache
(
0
),
engine
(
0
),
old_engine
(
0
),
used_tables_cache
(
0
),
have_to_be_excluded
(
0
),
const_item_cache
(
1
),
inside_first_fix_fields
(
0
),
done_first_fix_fields
(
FALSE
),
eliminated
(
FALSE
),
engine_changed
(
0
),
changed
(
0
),
is_correlated
(
FALSE
)
Item_result_field
(),
value_assigned
(
0
),
thd
(
0
),
old_engine
(
0
),
used_tables_cache
(
0
),
have_to_be_excluded
(
0
),
const_item_cache
(
1
),
inside_first_fix_fields
(
0
),
done_first_fix_fields
(
FALSE
),
substitution
(
0
),
expr_cache
(
0
),
engine
(
0
),
eliminated
(
FALSE
),
engine_changed
(
0
),
changed
(
0
),
is_correlated
(
FALSE
)
{
with_subselect
=
1
;
reset
();
...
...
sql/item_subselect.h
View file @
b77e3dc9
...
...
@@ -36,6 +36,22 @@ class Item_subselect :public Item_result_field
protected:
/* thread handler, will be assigned in fix_fields only */
THD
*
thd
;
/* old engine if engine was changed */
subselect_engine
*
old_engine
;
/* cache of used external tables */
table_map
used_tables_cache
;
/* allowed number of columns (1 for single value subqueries) */
uint
max_columns
;
/* where subquery is placed */
enum_parsing_place
parsing_place
;
/* work with 'substitution' */
bool
have_to_be_excluded
;
/* cache of constant state */
bool
const_item_cache
;
bool
inside_first_fix_fields
;
bool
done_first_fix_fields
;
public:
/*
Used inside Item_subselect::fix_fields() according to this scenario:
> Item_subselect::fix_fields
...
...
@@ -49,30 +65,12 @@ protected:
substitution= NULL;
< Item_subselect::fix_fields
*/
public:
Item
*
substitution
;
/* unit of subquery */
st_select_lex_unit
*
unit
;
Item
*
expr_cache
;
/* engine that perform execution of subselect (single select or union) */
subselect_engine
*
engine
;
protected:
/* old engine if engine was changed */
subselect_engine
*
old_engine
;
/* cache of used external tables */
table_map
used_tables_cache
;
/* allowed number of columns (1 for single value subqueries) */
uint
max_columns
;
/* where subquery is placed */
enum_parsing_place
parsing_place
;
/* work with 'substitution' */
bool
have_to_be_excluded
;
/* cache of constant state */
bool
const_item_cache
;
bool
inside_first_fix_fields
;
bool
done_first_fix_fields
;
public:
/* A reference from inside subquery predicate to somewhere outside of it */
class
Ref_to_outside
:
public
Sql_alloc
{
...
...
@@ -774,61 +772,26 @@ public:
of subselect_single_select_engine::[prepare | cols].
*/
subselect_single_select_engine
*
materialize_engine
;
protected:
/* The engine used to compute the IN predicate. */
subselect_engine
*
lookup_engine
;
/*
QEP to execute the subquery and materialize its result into a
temporary table. Created during the first call to exec().
*/
public:
JOIN
*
materialize_join
;
protected:
/* Keyparts of the only non-NULL composite index in a rowid merge. */
MY_BITMAP
non_null_key_parts
;
/* Keyparts of the single column indexes with NULL, one keypart per index. */
MY_BITMAP
partial_match_key_parts
;
uint
count_partial_match_columns
;
uint
count_null_only_columns
;
/*
A conjunction of all the equality condtions between all pairs of expressions
that are arguments of an IN predicate. We need these to post-filter some
IN results because index lookups sometimes match values that are actually
not equal to the search key in SQL terms.
*/
public:
*/
Item_cond_and
*
semi_join_conds
;
protected:
/* Possible execution strategies that can be used to compute hash semi-join.*/
enum
exec_strategy
{
UNDEFINED
,
COMPLETE_MATCH
,
/* Use regular index lookups. */
PARTIAL_MATCH
,
/* Use some partial matching strategy. */
PARTIAL_MATCH_MERGE
,
/* Use partial matching through index merging. */
PARTIAL_MATCH_SCAN
,
/* Use partial matching through table scan. */
IMPOSSIBLE
/* Subquery materialization is not applicable. */
};
/* The chosen execution strategy. Computed after materialization. */
exec_strategy
strategy
;
protected:
exec_strategy
get_strategy_using_schema
();
exec_strategy
get_strategy_using_data
();
ulonglong
rowid_merge_buff_size
(
bool
has_non_null_key
,
bool
has_covering_null_row
,
MY_BITMAP
*
partial_match_key_parts
);
void
choose_partial_match_strategy
(
bool
has_non_null_key
,
bool
has_covering_null_row
,
MY_BITMAP
*
partial_match_key_parts
);
bool
make_semi_join_conds
();
subselect_uniquesubquery_engine
*
make_unique_engine
();
public:
subselect_hash_sj_engine
(
THD
*
thd
,
Item_subselect
*
in_predicate
,
subselect_single_select_engine
*
old_engine
)
:
subselect_engine
(
thd
,
in_predicate
,
NULL
),
tmp_table
(
NULL
),
is_materialized
(
FALSE
),
materialize_engine
(
old_engine
),
lookup_engine
(
NULL
),
materialize_join
(
NULL
),
count_partial_match_columns
(
0
),
count_null_only_columns
(
0
),
semi_join_conds
(
NULL
),
strategy
(
UNDEFINED
)
:
subselect_engine
(
thd
,
in_predicate
,
NULL
),
tmp_table
(
NULL
),
is_materialized
(
FALSE
),
materialize_engine
(
old_engine
),
materialize_join
(
NULL
),
semi_join_conds
(
NULL
),
lookup_engine
(
NULL
),
count_partial_match_columns
(
0
),
count_null_only_columns
(
0
),
strategy
(
UNDEFINED
)
{}
~
subselect_hash_sj_engine
();
...
...
@@ -856,6 +819,38 @@ public:
//=>base class
bool
change_result
(
Item_subselect
*
si
,
select_result_interceptor
*
result
);
bool
no_tables
();
//=>base class
protected:
/* The engine used to compute the IN predicate. */
subselect_engine
*
lookup_engine
;
/* Keyparts of the only non-NULL composite index in a rowid merge. */
MY_BITMAP
non_null_key_parts
;
/* Keyparts of the single column indexes with NULL, one keypart per index. */
MY_BITMAP
partial_match_key_parts
;
uint
count_partial_match_columns
;
uint
count_null_only_columns
;
/* Possible execution strategies that can be used to compute hash semi-join.*/
enum
exec_strategy
{
UNDEFINED
,
COMPLETE_MATCH
,
/* Use regular index lookups. */
PARTIAL_MATCH
,
/* Use some partial matching strategy. */
PARTIAL_MATCH_MERGE
,
/* Use partial matching through index merging. */
PARTIAL_MATCH_SCAN
,
/* Use partial matching through table scan. */
IMPOSSIBLE
/* Subquery materialization is not applicable. */
};
/* The chosen execution strategy. Computed after materialization. */
exec_strategy
strategy
;
exec_strategy
get_strategy_using_schema
();
exec_strategy
get_strategy_using_data
();
ulonglong
rowid_merge_buff_size
(
bool
has_non_null_key
,
bool
has_covering_null_row
,
MY_BITMAP
*
partial_match_key_parts
);
void
choose_partial_match_strategy
(
bool
has_non_null_key
,
bool
has_covering_null_row
,
MY_BITMAP
*
partial_match_key_parts
);
bool
make_semi_join_conds
();
subselect_uniquesubquery_engine
*
make_unique_engine
();
};
...
...
sql/opt_subselect.cc
View file @
b77e3dc9
...
...
@@ -826,15 +826,12 @@ void get_delayed_table_estimates(TABLE *table,
((
subselect_hash_sj_engine
*
)
item
->
engine
);
JOIN
*
join
=
hash_sj_engine
->
materialize_join
;
double
rows
=
1
;
double
read_time
=
0.0
;
double
rows
;
double
read_time
;
/* Calculate #rows and cost of join execution */
for
(
uint
i
=
join
->
const_tables
;
i
<
join
->
tables
;
i
++
)
{
rows
*=
join
->
best_positions
[
i
].
records_read
;
read_time
+=
join
->
best_positions
[
i
].
read_time
;
}
get_partial_join_cost
(
join
,
join
->
tables
,
&
read_time
,
&
rows
);
*
out_rows
=
(
ha_rows
)
rows
;
*
startup_cost
=
read_time
;
/* Calculate cost of scanning the temptable */
...
...
sql/sql_join_cache.cc
View file @
b77e3dc9
...
...
@@ -185,6 +185,7 @@ void JOIN_CACHE::calc_record_fields()
start_tab
=
tab
;
if
(
start_tab
->
bush_children
)
start_tab
=
start_tab
->
bush_children
->
start
;
DBUG_ASSERT
(
!
start_tab
->
bush_children
);
tab
=
start_tab
;
...
...
@@ -508,7 +509,6 @@ void JOIN_CACHE::create_key_arg_fields()
/* Now create local fields that are used to build ref for this key access */
copy
=
field_descr
+
flag_fields
;
for
(
tab
=
start_tab
;
tab
!=
join_tab
;
tab
=
next_linear_tab
(
join
,
tab
,
FALSE
))
//for (tab= join_tab-tables; tab; tab= get_next_table(tab))
{
length
+=
add_table_data_fields_to_join_cache
(
tab
,
&
tab
->
table
->
tmp_set
,
&
data_field_count
,
&
copy
,
...
...
@@ -721,8 +721,11 @@ ulong JOIN_CACHE::get_min_join_buffer_size()
if
(
!
min_buff_size
)
{
size_t
len
=
0
;
for
(
JOIN_TAB
*
tab
=
start_tab
;
tab
!=
join_tab
;
tab
=
next_linear_tab
(
join
,
tab
,
FALSE
))
for
(
JOIN_TAB
*
tab
=
start_tab
;
tab
!=
join_tab
;
tab
=
next_linear_tab
(
join
,
tab
,
FALSE
))
{
len
+=
tab
->
get_max_used_fieldlength
();
}
len
+=
get_record_max_affix_length
()
+
get_max_key_addon_space_per_record
();
size_t
min_sz
=
len
*
min_records
;
size_t
add_sz
=
0
;
...
...
@@ -774,8 +777,11 @@ ulong JOIN_CACHE::get_max_join_buffer_size(bool optimize_buff_size)
size_t
max_sz
;
size_t
min_sz
=
get_min_join_buffer_size
();
size_t
len
=
0
;
for
(
JOIN_TAB
*
tab
=
start_tab
;
tab
!=
join_tab
;
tab
=
next_linear_tab
(
join
,
tab
,
FALSE
))
for
(
JOIN_TAB
*
tab
=
start_tab
;
tab
!=
join_tab
;
tab
=
next_linear_tab
(
join
,
tab
,
FALSE
))
{
len
+=
tab
->
get_used_fieldlength
();
}
len
+=
get_record_max_affix_length
();
avg_record_length
=
len
;
len
+=
get_max_key_addon_space_per_record
()
+
avg_aux_buffer_incr
;
...
...
sql/sql_select.cc
View file @
b77e3dc9
...
...
@@ -1035,31 +1035,15 @@ JOIN::optimize()
Perform the optimization on fields evaluation mentioned above
for all on expressions.
*/
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
TRUE
);
tab
;
tab
=
next_linear_tab
(
this
,
tab
,
TRUE
))
{
List_iterator
<
JOIN_TAB_RANGE
>
it
(
join_tab_ranges
);
JOIN_TAB_RANGE
*
jt_range
;
/* For upper level JOIN_TABs, we need to skip the const tables: */
uint
first_tab_offs
=
const_tables
;
while
((
jt_range
=
it
++
))
if
(
*
tab
->
on_expr_ref
)
{
for
(
JOIN_TAB
*
tab
=
jt_range
->
start
+
first_tab_offs
;
tab
<
jt_range
->
end
;
tab
++
)
{
if
(
*
tab
->
on_expr_ref
)
{
*
tab
->
on_expr_ref
=
substitute_for_best_equal_field
(
*
tab
->
on_expr_ref
,
tab
->
cond_equal
,
map2table
);
(
*
tab
->
on_expr_ref
)
->
update_used_tables
();
}
}
/*
Next jt_range will refer to SJM nest (and not the top-level range).
Inside SJM nests, we dont have const tables, so should start from the
first table:
*/
first_tab_offs
=
0
;
*
tab
->
on_expr_ref
=
substitute_for_best_equal_field
(
*
tab
->
on_expr_ref
,
tab
->
cond_equal
,
map2table
);
(
*
tab
->
on_expr_ref
)
->
update_used_tables
();
}
}
...
...
@@ -1067,47 +1051,34 @@ JOIN::optimize()
Perform the optimization on fields evaliation mentioned above
for all used ref items.
*/
//for (JOIN_TAB *tab= join_tab + const_tables; tab < join_tab + tables; tab++)
//{
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
TRUE
);
tab
;
tab
=
next_linear_tab
(
this
,
tab
,
TRUE
))
{
List_iterator
<
JOIN_TAB_RANGE
>
it
(
join_tab_ranges
);
JOIN_TAB_RANGE
*
jt_range
;
uint
first_tab_offs
=
const_tables
;
while
((
jt_range
=
it
++
))
{
for
(
JOIN_TAB
*
tab
=
jt_range
->
start
+
first_tab_offs
;
tab
<
jt_range
->
end
;
tab
++
)
{
uint
key_copy_index
=
0
;
for
(
uint
i
=
0
;
i
<
tab
->
ref
.
key_parts
;
i
++
)
{
Item
**
ref_item_ptr
=
tab
->
ref
.
items
+
i
;
Item
*
ref_item
=
*
ref_item_ptr
;
for
(
uint
i
=
0
;
i
<
tab
->
ref
.
key_parts
;
i
++
)
{
Item
**
ref_item_ptr
=
tab
->
ref
.
items
+
i
;
Item
*
ref_item
=
*
ref_item_ptr
;
if
(
!
ref_item
->
used_tables
()
&&
!
(
select_options
&
SELECT_DESCRIBE
))
continue
;
COND_EQUAL
*
equals
=
tab
->
first_inner
?
tab
->
first_inner
->
cond_equal
:
cond_equal
;
ref_item
=
substitute_for_best_equal_field
(
ref_item
,
equals
,
map2table
);
ref_item
->
update_used_tables
();
if
(
*
ref_item_ptr
!=
ref_item
)
{
*
ref_item_ptr
=
ref_item
;
Item
*
item
=
ref_item
->
real_item
();
COND_EQUAL
*
equals
=
tab
->
first_inner
?
tab
->
first_inner
->
cond_equal
:
cond_equal
;
ref_item
=
substitute_for_best_equal_field
(
ref_item
,
equals
,
map2table
);
ref_item
->
update_used_tables
();
if
(
*
ref_item_ptr
!=
ref_item
)
{
*
ref_item_ptr
=
ref_item
;
Item
*
item
=
ref_item
->
real_item
();
store_key
*
key_copy
=
tab
->
ref
.
key_copy
[
key_copy_index
];
if
(
key_copy
->
type
()
==
store_key
::
FIELD_STORE_KEY
)
{
store_key_field
*
field_copy
=
((
store_key_field
*
)
key_copy
);
field_copy
->
change_source_field
((
Item_field
*
)
item
);
}
}
key_copy_index
++
;
if
(
key_copy
->
type
()
==
store_key
::
FIELD_STORE_KEY
)
{
store_key_field
*
field_copy
=
((
store_key_field
*
)
key_copy
);
field_copy
->
change_source_field
((
Item_field
*
)
item
);
}
}
first_tab_offs
=
0
;
key_copy_index
++
;
}
}
//}
if
(
conds
&&
const_table_map
!=
found_const_table_map
&&
(
select_options
&
SELECT_DESCRIBE
))
...
...
@@ -1638,9 +1609,6 @@ bool JOIN::setup_subquery_caches()
for
(
JOIN_TAB
*
tab
=
first_linear_tab
(
this
,
TRUE
);
tab
;
tab
=
next_linear_tab
(
this
,
tab
,
TRUE
))
//for (JOIN_TAB *tab= join_tab + const_tables;
// tab < join_tab + tables ;
// tab++)
{
if
(
tab
->
select_cond
)
tab
->
select_cond
=
...
...
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