section about SELECT performing
This commit is contained in:
parent
aadf481f49
commit
b5403e65ca
@ -53,6 +53,7 @@ This is a manual about @strong{MySQL} internals.
|
|||||||
* caching:: How MySQL Handles Caching
|
* caching:: How MySQL Handles Caching
|
||||||
* flush tables:: How MySQL Handles @code{FLUSH TABLES}
|
* flush tables:: How MySQL Handles @code{FLUSH TABLES}
|
||||||
* filesort:: How MySQL Does Sorting (@code{filesort})
|
* filesort:: How MySQL Does Sorting (@code{filesort})
|
||||||
|
* selects:: How MySQL performs different selects
|
||||||
* coding guidelines:: Coding Guidelines
|
* coding guidelines:: Coding Guidelines
|
||||||
* mysys functions:: Functions In The @code{mysys} Library
|
* mysys functions:: Functions In The @code{mysys} Library
|
||||||
* DBUG:: DBUG Tags To Use
|
* DBUG:: DBUG Tags To Use
|
||||||
@ -220,7 +221,7 @@ After this it will give other threads a chance to open the same tables.
|
|||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
@node filesort, coding guidelines, flush tables, Top
|
@node filesort, selects, flush tables, Top
|
||||||
@chapter How MySQL Does Sorting (@code{filesort})
|
@chapter How MySQL Does Sorting (@code{filesort})
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@ -260,8 +261,350 @@ and then we read the rows in the sorted order into a row buffer
|
|||||||
|
|
||||||
@end itemize
|
@end itemize
|
||||||
|
|
||||||
|
@node selects, coding guidelines, flush tables, Top
|
||||||
|
@chapter How MySQL performs different selects
|
||||||
|
|
||||||
@node coding guidelines, mysys functions, filesort, Top
|
@node select steps,,,
|
||||||
|
@section Steps of select executing
|
||||||
|
|
||||||
|
Every select performed in such base steps:
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
JOIN::prepare
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
initialization and linking JOIN structure to st_select_lex
|
||||||
|
@item
|
||||||
|
fix_fields() for all items (after fix_fields we know everything
|
||||||
|
about item)
|
||||||
|
@item
|
||||||
|
moving HAVING to WHERE if possible
|
||||||
|
@item
|
||||||
|
initialization procedure if exists
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
JOIN::optimize
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
single select optimization
|
||||||
|
@item
|
||||||
|
creation first temporary table if need
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
JOIN::exec
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
performing select (may be created second temporary table)
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
JOIN::cleanup
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
removing all temporary tables, other cleanup
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
JOIN::reinit
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
prepare all structures to SELECT executing (with JOIN::exec)
|
||||||
|
@end itemize
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@node select select_result
|
||||||
|
@section select_result CLASS
|
||||||
|
|
||||||
|
Very important role in SELECT performing have select_result class and
|
||||||
|
classes inherited from it (usually called with "select_" prefix). This
|
||||||
|
class provide interface for results transmitting.
|
||||||
|
|
||||||
|
Key methods in this class are following:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@strong{send_fields} sends giving item list headers (type, name, etc..)
|
||||||
|
@item
|
||||||
|
@strong{send_data} sends giving item list values as row of table of result
|
||||||
|
@item
|
||||||
|
@strong{send_error} send error to used used mainly for error interception,
|
||||||
|
making some operation and then ::send_error will be called.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
For example there are fillowing select_result classes:
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
@strong{select_send} used for sending results though network layer
|
||||||
|
@item
|
||||||
|
@strong{select_export} used for exporting data to file
|
||||||
|
@item
|
||||||
|
@strong{multi_delete} used for multi-delete
|
||||||
|
@item
|
||||||
|
@strong{select_insert} used for INSERT ... SELECT ...
|
||||||
|
@item
|
||||||
|
@strong{multi_update} used for multi-update
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@node select simple
|
||||||
|
@section SIMPLE or PRIMARY SELECT.
|
||||||
|
|
||||||
|
For performing single primary select SELECT used function mysql_select,
|
||||||
|
which:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
allocate JOIN;
|
||||||
|
@item
|
||||||
|
JOIN::prepare;
|
||||||
|
@item
|
||||||
|
JOIN::optimize;
|
||||||
|
@item
|
||||||
|
JOIN::exec;
|
||||||
|
@item
|
||||||
|
JOIN::cleanup.
|
||||||
|
@end itemize
|
||||||
|
In previous versions of mysql all SELECTs was performed with help of this
|
||||||
|
function and mysql_select() was not divided on parts.
|
||||||
|
|
||||||
|
@node select structure
|
||||||
|
@section Structure Of Complex Select
|
||||||
|
|
||||||
|
There 2 structures which describe SELECTS:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
st_select_lex (SELECT_LEX) it represent SELECT itself
|
||||||
|
@item
|
||||||
|
st_select_lex_unit (SELECT_LEX_UNIT) group several selects in bunch
|
||||||
|
@end itemize
|
||||||
|
and represent UNION operation (absence of UNION is union
|
||||||
|
with 1 SELECT and this structure present in any case). In future this
|
||||||
|
structure will be used for EXCEPT and INTERSECT.
|
||||||
|
|
||||||
|
For example:
|
||||||
|
@example
|
||||||
|
(SELECT ... )UNION(SELECT ... (SELECT...)...(SELECT...UNION...SELECT))
|
||||||
|
1 2 3 4 5 6 7
|
||||||
|
@end example
|
||||||
|
|
||||||
|
will be represent as
|
||||||
|
@example
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
level 1
|
||||||
|
SELECT_LEX_UNIT(2)
|
||||||
|
|
|
||||||
|
+---------------+
|
||||||
|
| |
|
||||||
|
SELECT_LEX(1) SELECT_LEX(3)
|
||||||
|
|
|
||||||
|
--------------- | ------------------------------------------------------
|
||||||
|
| level 2
|
||||||
|
+-------------------+
|
||||||
|
| |
|
||||||
|
SELECT_LEX_UNIT(4) SELECT_LEX_UNIT(6)
|
||||||
|
| |
|
||||||
|
| +--------------+
|
||||||
|
| | |
|
||||||
|
SELECT_LEX(4) SELECT_LEX(5) SELECT_LEX(7)
|
||||||
|
|
||||||
|
------------------------------------------------------------------------
|
||||||
|
@end example
|
||||||
|
Note: single subselect 4 have it's own SELECT_LEX_UNIT.
|
||||||
|
|
||||||
|
Most upper SELECT_LEX_UNIT (#2 in example) stored in LEX.
|
||||||
|
First and most upper SELECT_LEX (#1 in example) stored in LEX, too.
|
||||||
|
This two structures always exist.
|
||||||
|
|
||||||
|
In time of creating or performing any JOIN::* operation
|
||||||
|
LEX::current_select point on appropriate SELECT_LEX.
|
||||||
|
|
||||||
|
Only during parsing global (for whole UNION) ORDER_BY & LIMIT clauses
|
||||||
|
LEX::current_select points to SELECT_LEX_UNIT of this unit to store this
|
||||||
|
parameter in this SELECT_LEX_UNIT (SELECT_LEX and SELECT_LEX_UNIT are
|
||||||
|
inherited from st_select_lex_node).
|
||||||
|
|
||||||
|
@node select union
|
||||||
|
@section Non-Subselect UNIONs Executing
|
||||||
|
|
||||||
|
Non subselect unions performed with help of mysql_union(). for now it
|
||||||
|
divided on following steps:
|
||||||
|
@itemize
|
||||||
|
@item
|
||||||
|
st_select_lex_unit::prepare
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
create temporary table for union results storing (if UNION witout
|
||||||
|
ALL option, 'distinct' parameter will be passed to table creation
|
||||||
|
procedure). Types/lengths of table's fields will be determinated
|
||||||
|
by first SELECT item list.
|
||||||
|
@item
|
||||||
|
create select_union (inherited from select_result) which will
|
||||||
|
write selects results in this temporary table
|
||||||
|
@item
|
||||||
|
allocate JOIN and perform JOIN::prepare for all SELECTs belonged
|
||||||
|
to UNION
|
||||||
|
@end itemize
|
||||||
|
@item
|
||||||
|
st_select_lex_unit::exec
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
delete rows from temporary table if it is not first call
|
||||||
|
@item
|
||||||
|
if first call call JOIN::optimize else JOIN::reinit and then
|
||||||
|
JOIN::exec for all SELECTs (select_union will write result for
|
||||||
|
temporary table). If union is cacheable and this method called
|
||||||
|
second, (third, ...) time it will do nothing.
|
||||||
|
@item
|
||||||
|
call mysql_select on temporary table with global ORDER BY and
|
||||||
|
LIMIT parameters after collecting results from all SELECTs.
|
||||||
|
@end itemize
|
||||||
|
@end itemize
|
||||||
|
As far as mysql_select need SELECT_LEX structure SELECT_LEX of first
|
||||||
|
SELECT of this UNION will be passed to it, but also fake_select_lex
|
||||||
|
parameter will be passed to mysql_select() too, to prevent linking
|
||||||
|
this SELECT_LEX with JOIN on this mysql_select() session.
|
||||||
|
|
||||||
|
PROBLEM: this fake select need workaround in many places.
|
||||||
|
|
||||||
|
@node select derived
|
||||||
|
@section Derived Tables Executing
|
||||||
|
|
||||||
|
Derived tables processing is first operation on any query. It performed
|
||||||
|
before creation list of tables of whole query and opening/locking this
|
||||||
|
tables.
|
||||||
|
|
||||||
|
If lex->derived_tables flag present will be scanned all SELECT_LEX (there
|
||||||
|
are list of all SELECT_LEX in reverse order (first SELECT in query will
|
||||||
|
be last in this list) lex->all_selects_list).
|
||||||
|
|
||||||
|
Pointer on derived table SELECT_LEX_UNIT stored in TABLE_LIST structure
|
||||||
|
(TABLE_LIST::derived). And for any table which have this pointer will
|
||||||
|
be called mysql_derived().
|
||||||
|
|
||||||
|
mysql_derived():
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
Creates list of all tables used in this query, opens and locks it
|
||||||
|
@item
|
||||||
|
Creates temporary table for storing results
|
||||||
|
@item
|
||||||
|
Creates union_result for writing result in this table
|
||||||
|
@item
|
||||||
|
Calls mysql_select or mysql_union for execute query
|
||||||
|
@item
|
||||||
|
Removes all derived table subtree from SELECTs tree (if it is
|
||||||
|
not EXPLAIN)
|
||||||
|
@item
|
||||||
|
Stores pointer to this temporary table in TABLE_LIST structure, then
|
||||||
|
this table will be used by outer query. This table table will not be
|
||||||
|
skipped in checking grants, because tables from which this table was
|
||||||
|
received was checked in mysql_derived.
|
||||||
|
@item
|
||||||
|
Links this temporary table in thd->derived_tables for removing after
|
||||||
|
query executing. this table will be closed in close_thread_tables if
|
||||||
|
second parameter of it (bool skip_derived) will be true.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@node select subselect
|
||||||
|
@section Subselects
|
||||||
|
|
||||||
|
In expression subselect represented by Item inherited from Item_subselect.
|
||||||
|
|
||||||
|
To hide difference in performing single SELECTs and UNIONs
|
||||||
|
Item_subselect use two different engines, which provide uniformed
|
||||||
|
interface for access to underplaid SELECT or UNION
|
||||||
|
(subselect_single_select_engine and subselect_union_engine, both are
|
||||||
|
inherited from subselect_engine).
|
||||||
|
|
||||||
|
Engine will be created in time of Item_select constructing
|
||||||
|
(Item_subselect::init method).
|
||||||
|
|
||||||
|
On Item_subselect::fix_fields() will be called engine->prepare().
|
||||||
|
|
||||||
|
Before calling any value getting method (val, val_int, val_str,
|
||||||
|
bring_value (in case of row result)) will be called engine->exec(),
|
||||||
|
which execute query or just do nothing if subselect is cacheable and
|
||||||
|
already executed.
|
||||||
|
|
||||||
|
Items inherited from provide it's own select_result classes. There are
|
||||||
|
2 type of it:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
select_singlerow_subselect it store values of giving row in
|
||||||
|
Item_singlerow_subselect cache on send_data() call and report error
|
||||||
|
if Item_subselect have 'assigned' attribute.
|
||||||
|
@item
|
||||||
|
select_exists_subselect just store 1 as value of
|
||||||
|
Item_exists_subselect on send_data() call. As far as
|
||||||
|
Item_in_subselect and Item_allany_subselect inherited from
|
||||||
|
Item_exists_subselect, they use same select_result class.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
Item_select will never call cleanup() procedure for JOIN. Every
|
||||||
|
JOIN::cleanup will call cleanup() for inner JOINs. Most upper
|
||||||
|
JOIN::cleanup will be called by mysql_select() or mysql_union().
|
||||||
|
|
||||||
|
@node select select engine
|
||||||
|
@section Single Select Engine
|
||||||
|
|
||||||
|
subselect_single_select_engine:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@strong{constructor} allocate JOIN and store pointers on SELECT_LEX and JOIN
|
||||||
|
@item
|
||||||
|
@strong{prepare()} call JOIN::prepare
|
||||||
|
@item
|
||||||
|
@strong{fix_length_and_dec()} prepare cache and receive type and
|
||||||
|
parameters of returning items (it called only by
|
||||||
|
Item_singlerow_subselect)
|
||||||
|
@item
|
||||||
|
@strong{exec()} drop 'assigned flag of Item_subselect. If called first time
|
||||||
|
JOIN::optimize and JOINexec(), else do nothing or JOIN::reinit()
|
||||||
|
JOIN::exec() depending of type of subquery.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@node select union engine
|
||||||
|
@section Union Engine
|
||||||
|
|
||||||
|
subselect_union_engine:
|
||||||
|
@itemize @bullet
|
||||||
|
@item
|
||||||
|
@strong{constructor} just store pointer to st_select_lex_union
|
||||||
|
(SELECT_LEX_UNION)
|
||||||
|
@item
|
||||||
|
@strong{prepare()} call st_select_lex_unit::prepare
|
||||||
|
@item
|
||||||
|
@strong{fix_length_and_dec()} prepare cache and receive type and
|
||||||
|
parameters (maximum of length) of returning items (it called
|
||||||
|
only by Item_singlerow_subselect)
|
||||||
|
@item
|
||||||
|
@strong{exec()} call st_select_lex_unit::exec(). st_select_lex_unit::exec()
|
||||||
|
can drop 'assigned' flag of Item_subselect if
|
||||||
|
st_select_lex_unit::item is not 0.
|
||||||
|
@end itemize
|
||||||
|
|
||||||
|
@node selectexplain
|
||||||
|
@section Explain Execution
|
||||||
|
|
||||||
|
For EXPLAIN result showing for every SELECT will be called mysql_select
|
||||||
|
with option SELECT_DESCRIBE.
|
||||||
|
|
||||||
|
For main UNION will be called mysql_explain_union.
|
||||||
|
|
||||||
|
mysql_explain_union call mysql_explain_select for every SELECT in given
|
||||||
|
union.
|
||||||
|
|
||||||
|
mysql_explain_select call mysql_select with SELECT_DESCRIBE.
|
||||||
|
|
||||||
|
mysql_select create JOIN for select (if it not exists, because if it
|
||||||
|
called for subselect JOIN can be created in JOIN::optimize of outer
|
||||||
|
query when it decided to calculate value of subselect). Then it call
|
||||||
|
JOIN::prepare, JOIN::optimize, JOIN exec and JOIN::cleanup as usual.
|
||||||
|
|
||||||
|
JOIN::exec called for SELECT with SELECT_DESCRIBE option call
|
||||||
|
select_describe.
|
||||||
|
|
||||||
|
select_describe return to user description of SELECT and call
|
||||||
|
mysql_explain_union for every inner UNION
|
||||||
|
|
||||||
|
PROBLEM: how it will work with global query optimization?
|
||||||
|
|
||||||
|
@node coding guidelines, mysys functions, selects, Top
|
||||||
@chapter Coding Guidelines
|
@chapter Coding Guidelines
|
||||||
|
|
||||||
@itemize @bullet
|
@itemize @bullet
|
||||||
@ -1836,7 +2179,7 @@ able to provide the optimal information for all parameters.
|
|||||||
|
|
||||||
If number of columns, in the header packet, is not 0 then the
|
If number of columns, in the header packet, is not 0 then the
|
||||||
prepared statement will contain a result set. In this case the packet
|
prepared statement will contain a result set. In this case the packet
|
||||||
is followed by a field description result set. @xref{4.1 field descr}.
|
is followed by a field description result set. @xref{4.1 field desc}.
|
||||||
|
|
||||||
|
|
||||||
@node 4.1 long data,,,
|
@node 4.1 long data,,,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user