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
b5403e65
Commit
b5403e65
authored
Feb 18, 2003
by
bell@sanja.is.com.ua
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
section about SELECT performing
parent
aadf481f
Changes
1
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
346 additions
and
3 deletions
+346
-3
Docs/internals.texi
Docs/internals.texi
+346
-3
No files found.
Docs/internals.texi
View file @
b5403e65
...
...
@@ -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 guideline
s, flush tables, Top
@node filesort,
select
s, 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 desc
r
}
.
is followed by a field description result set. @xref
{
4.1 field desc
}
.
@node 4.1 long data,,,
...
...
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