[MDEV-21633] Assertion `tmp >= 0' failed in best_access_path with rowid_filter=ON Created: 2020-02-02 Updated: 2023-11-28 |
|
| Status: | Stalled |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.4, 10.5, 10.6, 10.7, 10.8, 10.9 |
| Fix Version/s: | 10.4, 10.5, 10.6, 10.11 |
| Type: | Bug | Priority: | Major |
| Reporter: | Elena Stepanova | Assignee: | Igor Babaev |
| Resolution: | Unresolved | Votes: | 1 |
| Labels: | not-11.0+ | ||
| Issue Links: |
|
||||||||||||||||||||||||||||||||||||||||
| Description |
|
EXPLAIN also crashes. |
| Comments |
| Comment by Igor Babaev [ 2020-02-04 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Analysis: Most probably the bug can be reproduced with 10.1 with some other tests cases I would recommend to add the assertion
before the code
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2020-02-06 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Let's turn rowid filter optimization off to avoid crashes
and slightly change the query to make (s->quick->read_time + cmp_time) negative
Now let's enable optimizer trace, run the query and read optimizer trace. We see that the cost to join table t2 is
This is really no good.
Again optimizer trace reports the cost as "cost": 2e308
Now let's get the best execution plan for the query:
We see that the optimizer chooses the join order (t3,t1) and employs a join cache
though the plan that uses the join order (t1,t3) and a ref access to t3 is apparently cheaper. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2020-02-28 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Studying why does the optimizer get a cost of 2e308 for the query:
Indexes:
Range analysis: table_rows=100.
calculate_cond_selectivity_for_table() starts to compute the selectivity by first taking into account indexes with more key parts. index a_2: selectivity=0.34 Indexes PK and a are then not taken into account as their first component is already "handled" by quick select on a_2. As a result, table->cond_selectivity=0.34. Then we reach best_access_path:
cmp_time is negative.
Here
Then we compute
and the result of computation is COST_MAX. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Alice Sherepa [ 2020-08-07 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Somehow test from the description passes on 10.5 bbd70fcc43cc889e4593594ee5, but test from
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-05 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
The problem can be demonstrated with the following example:
Let's see what we have in EXPLAIN EXTENDED for this query:
So it is expected about 27 rows (280*9.50) in the result set. I fact we have:
Let's see at the selectivities of the range conditions.
For the condition (b in (3,1)) we have:
For the condition ( c between 100 and 129) we have:
So far so good.
This is not good at all: the optimizer decides that the selectivity of the condition
Now we have:
Now we see that selectivity of the condition (b in (3,1,13)) is partly ignored. Actually selectivity only of these sub-ranges are taken into account: (a=5 and b < 1) and (a=7 and b > 13):
| ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-05 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Now let's see how the ignored selectivity of the condition (a between 5 and 7) affects the optimizer choice of the best execution plan for the query:
We saw that the optimizer chose a plan with the join order (t2,t1):
Lets see how good it is:
Let's force the join order (t1,t2):
We see that the chosen plan is actually essentially worse than the last one. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2021-11-06 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Here are some other observations we can get when looking through the optimizer trace for the query:
The above means that the best single-index range scan is by index b that is expected to fetch 89 records and its cost is 113.71.
The debugger shows that the best access is still the range scan by index b. Yet all of a sudden its cost has become smaller while the expected number of records to scan has become bigger. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2022-04-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I checked the original query that caused a crash with 10.7-selectivty tree and this didn't crash. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Michael Widenius [ 2022-04-13 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
I checked also this query in the 10.7-selectivty tree: explain select * from t1 join t2 on fk1=pk1 where a between 5 and 7 and b in (3,1) and c between 100 and 129;
-----
----- Which is the better plan, as Igor showed above | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Comment by Alice Sherepa [ 2022-07-19 ] | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
the test below crashes in a similar way on current 10.5-10.11, but not on 11.0-11.3:
|