[MDEV-6402] Optimizer doesn't choose best execution plan when composite key is used. Created: 2014-06-27 Updated: 2018-12-19 Resolved: 2014-10-06 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.0.11 |
| Fix Version/s: | 10.1.1 |
| Type: | Bug | Priority: | Major |
| Reporter: | Seunguck Lee | Assignee: | Sergei Petrunia |
| Resolution: | Fixed | Votes: | 0 |
| Labels: | optimizer, order-by-optimization | ||
| Environment: |
Linux matt001 2.6.18-308.el5 #1 SMP Tue Feb 21 20:06:06 EST 2012 x86_64 x86_64 x86_64 GNU/Linux |
||
| Attachments: |
|
| Description |
|
MariaDB optimizer doesn't choose best execution plan when they use composite key. There's composite key with two columns (pk1 + fd5). See below test case. Test case ------------------------------------------------------------------------------
|
| Comments |
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
I tried to create a dataset that would match the provided descriptions. I used these two queries
and I got this:
| ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
Both queries run in 0.00 sec for me. However, it is still peculiar that we would use a ref access where there is a possible range access on the same index that will scan a proper subset of the records. The original bug report shows a situation where range access reads fewer records. | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
I've tried to replicate the situation from the bug report. the choice seems to depend on thevalues of the constants. When the range is very small, both queries pick range(2 keyparts):
when the range gets bigger, the query without hint switches to ref(one keypart):
| ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
The above experiments were done on a tree that didn't have the fix for | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
Debugging... test_if_skip_sort_order() finds that ref(PRIMARY) does not provide the desired The code has a special branch that handles cases when there is another index
We don't make a choice between ref and range access, we use ref | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-09 ] | ||||||||||||||||||||||||||
|
Debugging, #rows and costs: == range optimization ==
This gets returned as tab->quick. === ux_pk1_fd5 ===
== Join optimization == === PRIMARY ===
This ref is picked as best. Note that its cost is much smaller than cost of range access over the same interval. The difference is caused by range optimizer adding "CPU cost" (which is cpu_cost = 11135.610 > io_cost) === ux_pk1_fd5 ===
again, range access's CPU cost is not added here.
== test_if_skip_sort_order == | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-10 ] | ||||||||||||||||||||||||||
|
Test dataset fill script, mdev6402-dataset1.sql | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-10 ] | ||||||||||||||||||||||||||
|
Observations about cost calculations: #rows is very close for the PRIMARY key and for ux_pk1_fd5. Then, test_if_skip_sort_order() doesn't care about costs. It changes to using | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-07-10 ] | ||||||||||||||||||||||||||
|
Possible solutions == CHECK-RANGE-ALSO == == REF-IS-THE-FIRST-STEP == | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-09-09 ] | ||||||||||||||||||||||||||
|
Re-tried on 10.1 with fixes for | ||||||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2014-09-12 ] | ||||||||||||||||||||||||||
|
Pushed a patch here: https://github.com/MariaDB/server/tree/bb-10.1-mdev6402 elenst, I need a testing pass for this tree. | ||||||||||||||||||||||||||
| Comment by George Diamantopoulos [ 2018-12-19 ] | ||||||||||||||||||||||||||
|
I think there might be a regression with 10.3.11 but it also may be a different issue. My use case is similar, composite primary key with (id, date), indexes for date and callid. `date` and `callid` used in WHERE clause, `id` in ORDER BY clause. Mariadb version is: 10.3.11-MariaDB-1:10.3.11+maria~stretch-log mariadb.org binary distribution This is a galera cluster installation, in case it makes any difference. With ORDER BY clause key selection is sub-optimal, leading to the query taking a long time. Without ORDER BY clause, execution is very fast. I've pasted more information at https://pastebin.com/dPWEBs25 Please let me know if I need to open a separate issue for this... |