[MDEV-18808] Index_merge intersect plan is picked where ref access would be faster Created: 2019-03-04 Updated: 2020-04-27 |
|
| Status: | Open |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.4 |
| Fix Version/s: | 10.4 |
| Type: | Bug | Priority: | Major |
| Reporter: | Sergei Petrunia | Assignee: | Sergei Petrunia |
| Resolution: | Unresolved | Votes: | 0 |
| Labels: | index_merge | ||
| Attachments: |
|
| Description |
|
(I am using 10.4 for debugging but this most likely affects earlier versions too) Use the attached file to fill the dataset and then we get this table
The query
Produces this query plan:
This is much slower than just doing a ref access on customer_id. Data distribution for is_processed is as follows
so the condition "is_processed=1" has 99% selectivity. |
| Comments |
| Comment by Sergei Petrunia [ 2019-03-04 ] | |||||||||||||||||
|
Index_merge uses "Using index", and is not reading full table rows, while ref access on customer_id would read full table rows. This should not be relevant in this case, though, because the condition on is_processed has 99% selectivity. It is hard to believe that scanning 99% of the secondary index is cheaper than reading full table rows for rows that match "customer_id=10000". This is especially true for the example we are looking at - rows in the table `orders` are not large. | |||||||||||||||||
| Comment by Sergei Petrunia [ 2019-03-04 ] | |||||||||||||||||
|
Looking at optimizer trace:
The estimate for #rows on "is_processed=1" is 500K rows. (Is this a known problem with InnoDB that records_in_range() may return rows_in_table/2, even when the range covers a much greater portion of the index. See MDEV-17111 for example, and it was observed on other occasions, too). Overly-optimistic estimate from records_in_range() might be one, but not the sole cause of this issue. | |||||||||||||||||
| Comment by Sergei Petrunia [ 2019-03-04 ] | |||||||||||||||||
|
Query execution times:
0.04 sec
0.22 sec | |||||||||||||||||
| Comment by Jesse [ 2020-04-27 ] | |||||||||||||||||
|
Few more tests 1. Customer with few orders
2. customer with 10000+ orders and the one above IN
3. customer with 10000+ orders and non-existing customer_id IN
4. and the slow one just for customer with 10000+ orders
Which can be fixed with index hint for customer_id or
|