[MDEV-23174] SELECT with a complex WHERE clause is not using range access Created: 2020-07-14 Updated: 2024-02-07 Resolved: 2024-02-07 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.3.22 |
| Fix Version/s: | N/A |
| Type: | Bug | Priority: | Critical |
| Reporter: | Sergei Petrunia | Assignee: | Maria M Pflaum |
| Resolution: | Incomplete | Votes: | 2 |
| Labels: | optimizer-hard | ||
| Description |
|
A single-table SELECT with a complex WHERE clause uses range access in MariaDB 5.2 and full table scan in MariaDB 10.3.22. (The query and table DDLs are available but they are customer' data. Dataset is not available but one doesn't need it to demonstrate the issue) |
| Comments |
| Comment by Sergei Petrunia [ 2020-07-14 ] | ||||||||||||||||||||
|
It happens, because statement_should_be_aborted() eventually returns true:
it does because alloced_sel_args > SEL_ARG::MAX_SEL_ARGS. The code that calls this:
| ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-14 ] | ||||||||||||||||||||
|
About the limit: The limit is: MAX_SEL_ARGS =16000 | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-15 ] | ||||||||||||||||||||
|
The code that introduced the statement_should_be_aborted():
It was committed twice (a rebase?): | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-15 ] | ||||||||||||||||||||
|
In 5.2.14, the execution also hits the param->alloced_sel_args=16000 limit
The difference is that after this, it still returns the tree that it has managed to build and apparently that is sufficient to get a decent query plan. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-15 ] | ||||||||||||||||||||
This patch is not the cause of the issue. Running on 5.5.31 (the version before the patch was introduced) I get the same result - get_mm_tree() returns NULL. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-15 ] | ||||||||||||||||||||
|
If I change the logic around statement_should_be_aborted() call from "abort for all cases":
to "abort for the first three, but return the tree built so far if alloced_sel_args > SEL_ARG::MAX_SEL_ARGS " then the code produces some SEL_TREE objects. It difficult to tell if these are the same as ones in 5.2. The SEL_TREEs are very large so manual comparison is out of the question. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-07-17 ] | ||||||||||||||||||||
|
... alas, they seem to be different. If I print records_in_range() calls made, I can see that: Both 5.2 and fixed-10.3 print the same number of ranges for key=0. For key=1:
5.2 gets 668 ranges in form
Also, 5.2 gets ranges for key=6 while 10.3 doesn't. | ||||||||||||||||||||
| Comment by Roel Van de Paar [ 2021-09-23 ] | ||||||||||||||||||||
|
julien.fritsch There is no need to, clearly psergei already understands the issue at hand. I confirmed it based on this. psergei can revert if necessary. | ||||||||||||||||||||
| Comment by Sergei Petrunia [ 2023-10-11 ] | ||||||||||||||||||||
|
This patch was pushed to 10.6.16 and up:
It is not a fix for this issue but now one can try a workaround by setting optimizer_max_sel_args to a higher number. |