summaryrefslogtreecommitdiff
path: root/Docs
diff options
context:
space:
mode:
authorunknown <bell@sanja.is.com.ua>2003-02-18 18:42:30 +0200
committerunknown <bell@sanja.is.com.ua>2003-02-18 18:42:30 +0200
commit3f04d9b73f88fa0fac0875a91ccc3da15bf60064 (patch)
treef949b85f093bc4d321bf85cf4719764a75ff5462 /Docs
parent49e6a2d0e443f5ba788026a6f9218db12ad23cc4 (diff)
downloadmariadb-git-3f04d9b73f88fa0fac0875a91ccc3da15bf60064.tar.gz
section about SELECT performing
Diffstat (limited to 'Docs')
-rw-r--r--Docs/internals.texi349
1 files changed, 346 insertions, 3 deletions
diff --git a/Docs/internals.texi b/Docs/internals.texi
index eac0fd11a07..5a868aebf62 100644
--- a/Docs/internals.texi
+++ b/Docs/internals.texi
@@ -53,6 +53,7 @@ This is a manual about @strong{MySQL} internals.
* caching:: How MySQL Handles Caching
* flush tables:: How MySQL Handles @code{FLUSH TABLES}
* filesort:: How MySQL Does Sorting (@code{filesort})
+* selects:: How MySQL performs different selects
* coding guidelines:: Coding Guidelines
* mysys functions:: Functions In The @code{mysys} Library
* 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
-@node filesort, coding guidelines, flush tables, Top
+@node filesort, selects, flush tables, Top
@chapter How MySQL Does Sorting (@code{filesort})
@itemize @bullet
@@ -260,8 +261,350 @@ and then we read the rows in the sorted order into a row buffer
@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
@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
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,,,