[MDEV-20900] IN predicate to IN subquery conversion causes performance regression Created: 2019-10-26 Updated: 2021-04-27 Resolved: 2019-12-10 |
|
| Status: | Closed |
| Project: | MariaDB Server |
| Component/s: | Optimizer |
| Affects Version/s: | 10.3.18, 10.4.8 |
| Fix Version/s: | 10.3.22, 10.4.12, 10.5.1 |
| Type: | Bug | Priority: | Major |
| Reporter: | Alex Babanski | Assignee: | Varun Gupta (Inactive) |
| Resolution: | Fixed | Votes: | 1 |
| Labels: | optimizer, performance | ||
| Environment: |
Debian Linux Buster and Stretch |
||
| Attachments: |
|
||||||||||||||||||||||||
| Issue Links: |
|
||||||||||||||||||||||||
| Description |
|
This issue affects Magento2 (leading eCommerce CRM): https://magento.com/ Magento2 is using Entity-Attribute-Value model (EAV), also known as object-attribute-value. As a result, there are multiple "IN " statements in queries. Here is one of the problematic queries: In MariaDB 10.1 and 10.2 and also MySQL 8 it's a SIMPLE execution plan that takes 6 seconds: 95210 rows in set (5.58 sec) On MariaDB 10.3 and 10.4 on the same server with the same settings (including optimizer_switch) it's now 35 mins: However, there is no way to disable subqueries in The database is about 7GB and contains sensitive data. That's why I didn't attach it to this issue. It is available on request. |
| Comments |
| Comment by Varun Gupta (Inactive) [ 2019-10-27 ] | |||||||||||||||||||||||
|
in_predicate_conversion_threshold now works on release builds too, this was fixed in https://jira.mariadb.org/browse/MDEV-16871. Should be available with 10.3.18 onwards. | |||||||||||||||||||||||
| Comment by Alex Babanski [ 2019-10-27 ] | |||||||||||||||||||||||
|
I set in_predicate_conversion_threshold to 0 in 10.3.18. | |||||||||||||||||||||||
| Comment by Alex Babanski [ 2019-10-27 ] | |||||||||||||||||||||||
|
I think this issue is related to | |||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2019-10-28 ] | |||||||||||||||||||||||
|
@Varun, what's the long term idea currently? @Alex, yes it seems so that you're being hit by that issue you can take your query and trim the IN list to 999 items to be sure... Basically in the new version some of problems related to this IN-subquery-expansion were fixed. Can't tell which ones, I have done some testing a like a month ago and some of the queries I had problems with started behaving "properly". In my company we have developed a system to compare everything we run on 10.1 with 10.4 and in_predicate_conversion_threshold is in fact working. BUT, it seems that it can't be set in config file for newest 10.4. Maybe it is just our installation but it always reverted to default value. Try doing it "manually" and issue SET GLOBAL in_predicate_conversion_threshold = 0 in the console, and hopefully the issues will be gone | |||||||||||||||||||||||
| Comment by Alex Babanski [ 2019-10-28 ] | |||||||||||||||||||||||
|
I tested it on both 10.3.18 and 10.4.8 and even though in_predicate_conversion_threshold is set to 0 in both console and in my.cnf, it has absolutely zero effect on the execution plan. I've tried initially with default options for optimizer_switch and then tried to disable flags introduced in 10.3 and 10.4 (for instance, rowid_filter=off, condition_pushdown_from_having=off, split_materialized=off, etc. ). Also, I've tried to change join_cache_level and played with join_buffer_space_limit, rowid_merge_buff_size, join_buffer_size - it had zero effect either. Unfortunately, there is no way for me to trim the query - it's part of Magento2 CRM system (means it affects a lot of sites - it's estimated that about 35% of all the ecommerce sites are magento2 sites). | |||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2019-10-28 ] | |||||||||||||||||||||||
|
Very strange, haven't observed that... and actually this new optimization is something which would make our servers to die due to starvation within couple of minutes, so i'm preety certain it's disabled as expected I remember that i thought it isn't working on the first try as well because when you're using SET GLOBAL you need to close the connection and open new one for it to have effect. Just after you set it try checking if it's in fact set properly to given value, if 0 won't work try setting to 4 billions instead. Maybe you're using persistent connections or connection pooling and that's why you still have issues. Stop all services, start mysql, do SET GLOBAL from console, only then start HTTP/pool. https://www.screencast.com/t/MwgkbWQYoM >Unfortunately, there is no way for me to trim the query | |||||||||||||||||||||||
| Comment by Alex Babanski [ 2019-10-28 ] | |||||||||||||||||||||||
|
Hello. | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-10-29 ] | |||||||||||||||||||||||
|
Hi babanski, yes it is a bug that in_predicate_coversion_threshold does not work in my.cnf file, i had just tried to do it in a session. I have fixed this and in the next release you can set this in the cnf file and it will work. Now coming to the second part to investigate why is there such a performance difference, can you share
| |||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2019-10-29 ] | |||||||||||||||||||||||
|
@Alex, that's great, good it helped When you see test case 1 AFAIR it's fixed in newest 10.4, but when you go to test 2 it isn't able to use indexes. I think Alex is having same issue i reported in "test case 2" because his query looks almost the same. So computational complexity goes from O ( n ) to O ( n^2 ) in worst case as i believe something which was just more-or-less a hash lookup in 10.1 and 10.2 - is converted to nested table scan in 10.3 and 10.4... | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-10-29 ] | |||||||||||||||||||||||
|
Hi pslawek83, is the type mismatch an important use case I can reproduce this with a smaller value for in_predicate_conversion_threshold
here id2 is an column with type INT, so here the types compared are INT with STRING, so here we can't have Semi join materialization as it expects the same type of the left and right hand side of the IN predicate(that got converted to a subquery). Lets now change id2 to id3 id3 is VARCHAR(255)
so here we use Semi Join materialization and this is making a lookup so this would be either faster(depends on number of duplicates) or would be the same. | |||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2019-10-29 ] | |||||||||||||||||||||||
|
Hi @Varun thank you for looking into this. Sure, I understand. Basically as for me the deal is that we're not having any memory-usage issues related to creating these in-memory-hash (or skiplist) structures which are used "normally", so we just disabled this optimization feature altogether and all works great for us. Not sure about @Alex, just wanted to point out that this seems to be the same issue, so you can probably "group" it with Quick comment about mismatching types, we actually are using strings for everything because we found out this way is safer. Eg. we're getting something from mysql as string and then we can query using string without worrying about eg. overflowing integer range, so we just got rid of one problem for us this way, as we're using large integers sometimes | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-11-01 ] | |||||||||||||||||||||||
|
Hi pslawek83 babanski, I discussed this issue with my team and it is decided that for different types we should disable this optimization. This is done as it would need some work to allow different types for this optimization and we would not like to push that change to GA versions. | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-11-04 ] | |||||||||||||||||||||||
|
Patch | |||||||||||||||||||||||
| Comment by Slawomir Pryczek [ 2019-11-07 ] | |||||||||||||||||||||||
|
Hi Varun, that's great news because issues related to this are rather hard to diagnose. It should improve user experience a lot, if you can disable IN(...) expansion for problematic cases... | |||||||||||||||||||||||
| Comment by Sergei Petrunia [ 2019-12-03 ] | |||||||||||||||||||||||
|
Review input: http://lists.askmonty.org/pipermail/commits/2019-December/014082.html . Small changes are needed. Also, please file the MDEV about handling a broader set of datatype comparison and link to this MDEV. | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-12-04 ] | |||||||||||||||||||||||
|
New Patch after review addressal http://lists.askmonty.org/pipermail/commits/2019-December/014083.html | |||||||||||||||||||||||
| Comment by Varun Gupta (Inactive) [ 2019-12-10 ] | |||||||||||||||||||||||
|
Has also created |