[MDEV-17155] Incorrect ORDER BY optimization: full index scan is used instead of range Created: 2018-09-07 Updated: 2020-08-25 Resolved: 2018-09-12 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.1, 10.2, 10.3 |
| Fix Version/s: | 10.2.18, 10.3.10, 10.1.37 |
| Type: | Bug | Priority: | Major |
| Reporter: | Sergei Petrunia | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | order-by-optimization | ||
| Description |
|
This is based on a customer testcase. I wasn't able to construct an actual testcase so far, but I was able to get the invalid query plan by tampering with rows/cost estimates in the debugger. The problem looks like this:
The plan uses a full index scan, even if there is a potential ref (or range) access over the PRIMARY key: pk1 = 700000. Costs and selectivity numbers are irrelevant - if we pick to do a full index scan, then range on that index will not be slower. The optimizer actually has this logic and was expected to use range access. It even typically does. Getting the above query plan requires some peculiar relationship between costs of range/ref accesses through key1 and primary key. |
| Comments |
| Comment by Sergei Petrunia [ 2018-09-07 ] | ||||||||||||||||||||||||||||||||||
|
Steps to reproduce: 1. Fill the dataset
2. In the debugger, put a breakpoint in get_key_scans_params after this call:
Condition for breakpoint: keynr == 1 Actions to do:
Continue execution. It should be that best_idx=1 after loop exit. 3. Put a breakpoint in best_access_path BEFORE this code:
On the second breakpoint hit, you will see tmp=10291 or something like that. Actions to do:
It should pick ref access on key1 Then continue execution and test_if_skip_sort_order/test_if_cheaper_ordering will choose to switch to PRIMARY key and use index scan. | ||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-09-07 ] | ||||||||||||||||||||||||||||||||||
|
I then follow the execution all the way to here
The calculations show that yes, it is better to switch to a quick select for the key PRIMARY.
| ||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-09-07 ] | ||||||||||||||||||||||||||||||||||
|
Where did the condition go... In the case that I am debugging it seems to be pushed down by Index Condition Pushdown:
Another potential concern is that if ref access was chosen, then the equalities that used to guarantee to be true were removed? JOIN::conds:
| ||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-09-07 ] | ||||||||||||||||||||||||||||||||||
They would be, but then add_ref_to_table_cond is called to put them back. So this is not a concern. | ||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-09-09 ] | ||||||||||||||||||||||||||||||||||
|
The patch: http://lists.askmonty.org/pipermail/commits/2018-September/012901.html | ||||||||||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2018-09-09 ] | ||||||||||||||||||||||||||||||||||
|
Igor please review | ||||||||||||||||||||||||||||||||||
| Comment by Igor Babaev [ 2018-09-11 ] | ||||||||||||||||||||||||||||||||||
|
ok to push | ||||||||||||||||||||||||||||||||||
| Comment by Manuel Arostegui [ 2018-12-05 ] | ||||||||||||||||||||||||||||||||||
|
I had this issue on my environment too, and 10.1.37 fixed it. The optimizer now behaves correctly |