PT-2340 - Support MySQL 8.4

- Updated documentation
This commit is contained in:
Sveta Smirnova
2024-08-30 18:45:28 +03:00
parent 2ca815650e
commit 94bcfd2b69
39 changed files with 565 additions and 1616 deletions

View File

@@ -2656,9 +2656,7 @@ bookmark lookup into the film_actor table.
=back
For more information on how to read EXPLAIN output, please see
L<http://dev.mysql.com/doc/en/explain.html>, and this talk titled
"MySQL query optimizer internals and upcoming features in v. 5.2":
from Timour Katchaounov, one of the MySQL developers: L<http://goo.gl/VIWvo>
L<http://dev.mysql.com/doc/en/explain.html>.
=head1 MODULES
@@ -2693,13 +2691,11 @@ trying to figure out how this works, but otherwise this section will probably
not make your life richer.
The tree can be built by examining the id, select_type, and table columns of
each row. Here's what I know about them:
each row.
The id column is the sequential number of the select. This does not indicate
nesting; it just comes from counting SELECT from the left of the SQL statement.
It's like capturing parentheses in a regular expression. A UNION RESULT row
doesn't have an id, because it isn't a SELECT. The source code actually refers
to UNIONs as a fake_lex, as I recall.
It's like capturing parentheses in a regular expression.
If two adjacent rows have the same id value, they are joined with the standard
single-sweep multi-join method.
@@ -2749,7 +2745,7 @@ access to the temporary table that holds the result of the subquery whose id is
N. If it says <unionN,..N> it's the same thing, but it refers to the results it
UNIONs together.
Finally, order matters. If a row's id is less than the one before it, I think
Finally, order matters. If a row's id is less than the one before it,
that means it is dependent on something other than the one before it. For
example,
@@ -2765,7 +2761,7 @@ example,
| 3 | SUBQUERY | film_actor |
| 2 | SUBQUERY | film |
If the results were in order 2-3-4, I think that would mean 3 is a subquery of
If the results were in order 2-3-4, that would mean 3 is a subquery of
2, 4 is a subquery of 3. As it is, this means 4 is a subquery of the nearest
previous recent row with a smaller id, which is 1. Likewise for 3 and 2.
@@ -2802,8 +2798,8 @@ following:
| NULL | UNION RESULT | <union5,6> |
| NULL | UNION RESULT | <union1,4> |
This would be a lot easier to work with if it looked like this (I've
bracketed the id on rows I moved):
This would be a lot easier to work with if it looked like this (we've
bracketed the id on rows we moved):
| id | select_type | table |
+------+--------------+------------+
@@ -2819,7 +2815,7 @@ bracketed the id on rows I moved):
In fact, why not re-number all the ids, so the PRIMARY row becomes 2, and so on?
That would make it even easier to read. Unfortunately that would also have the
effect of destroying the meaning of the id column, which I think is important to
effect of destroying the meaning of the id column, which is important to
preserve in the final tree. Also, though it makes it easier to read, it doesn't
make it easier to manipulate programmatically; so it's fine to leave them
numbered as they are.
@@ -2831,7 +2827,7 @@ the slice of rows that should be child nodes in the tree: you just look for the
first row whose ID is the same as the first number in the table.
The next question is how to find the last row that should be a child node of a
UNION or DERIVED. I'll start with DERIVED, because the solution makes UNION
UNION or DERIVED. We'll start with DERIVED, because the solution makes UNION
easy.
Consider how MySQL numbers the SELECTs sequentially according to their position
@@ -2871,14 +2867,14 @@ Here's the output of EXPLAIN:
| NULL | UNION RESULT | <union3,5> |
| 2 | DERIVED | film |
The siblings all have id 1, and the middle one I care about is derived3.
(Notice MySQL doesn't execute them in the order I defined them, which is fine).
Now notice that MySQL prints out the rows in the opposite order I defined the
subqueries: 6, 3, 2. It always seems to do this, and there might be other
The siblings all have id 1, and the middle one we care about is derived3.
(Notice MySQL doesn't execute them in the order they are defined, which is fine).
Now notice that MySQL prints out the rows in the opposite order the subqueries
were defined: 6, 3, 2. It always seems to do this, and there might be other
methods of finding the scope boundaries including looking for the lower boundary
of the next largest sibling, but this is a good enough heuristic. I am forced
to rely on it for non-DERIVED subqueries, so I rely on it here too. Therefore,
I decide that everything greater than or equal to 3 belongs to the DERIVED
of the next largest sibling, but this is a good enough heuristic. We are forced
to rely on it for non-DERIVED subqueries, so we rely on it here too. Therefore,
we decide that everything greater than or equal to 3 belongs to the DERIVED
scope.
The rule for UNION is simple: they consume the entire enclosing scope, and to
@@ -2894,8 +2890,8 @@ the enclosing scope's boundaries, and the rest is easy. Notice in the example
above, the UNION is over <union3,5>, which includes the row with id 4 -- it
includes every row between 3 and 5.
Finally, there are non-derived subqueries to deal with as well. In this case I
can't look at siblings to find the end of the scope as I did for DERIVED. I
Finally, there are non-derived subqueries to deal with as well. In this case we
can't look at siblings to find the end of the scope as we did for DERIVED. We
have to trust that MySQL executes depth-first. Here's an example:
explain
@@ -2950,16 +2946,14 @@ select 4 came first. In other words, if EXPLAIN looked like this,
| 4 | DEPENDENT SUBQUERY | actor |
I would be forced to assume upon seeing select 3 that select 4 is a subquery
of it, rather than just being the next sibling in the enclosing scope. If this
is ever wrong, then the algorithm is wrong, and I don't see what could be done
about it.
of it, rather than just being the next sibling in the enclosing scope.
UNION is a little more complicated than just "the entire scope is a UNION,"
because the UNION might itself be inside an enclosing scope that's only
indicated by the first item inside the UNION. There are only three kinds of
enclosing scopes: UNION, DERIVED, and SUBQUERY. A UNION can't enclose a UNION,
and a DERIVED has its own "scope markers," but a SUBQUERY can wholly enclose a
UNION, like this strange example on the empty table t1:
and a DERIVED has its own "scope markers," but a SUBQUERY in earlier versions
could wholly enclose a UNION, like this strange example on the empty table t1:
explain select * from t1 where not exists(
(select t11.i from t1 t11) union (select t12.i from t1 t12));
@@ -2974,12 +2968,8 @@ UNION, like this strange example on the empty table t1:
The UNION's backward references might make it look like the UNION encloses the
subquery, but studying the query makes it clear this isn't the case. So when a
UNION's first row says SUBQUERY, it is this special case.
By the way, I don't fully understand this query plan; there are 4 numbered
SELECT in the plan, but only 3 in the query. The parens around the UNIONs are
meaningful. Removing them will make the EXPLAIN different. Please tell me how
and why this works if you know.
UNION's first row says SUBQUERY, it is this special case that we cannot repeat
starting from MySQL 5.7.
Armed with this knowledge, it's possible to use recursion to turn the
parent-child relationship between all the rows into a tree representing the
@@ -3011,8 +3001,7 @@ The execution plan looks like a depth-first traversal of this tree:
The JOIN might not be a JOIN. It might be a subquery, for example. This comes
from the type column of EXPLAIN. The documentation says this is a "join type,"
but I think "access type" is more accurate, because it's "how MySQL accesses
rows."
but "access type" may be more accurate, because it's "how MySQL accesses rows."
pt-visual-explain decorates the tree significantly more than just turning
rows into nodes. Each node may get a series of transformations that turn it
@@ -3217,6 +3206,12 @@ dsn: user; copy: yes
User for login if not current user.
=item * s
dsn: mysql_ssl; copy: yes
Create SSL connection
=back
=head1 ENVIRONMENT