I'm having a strange ActiveRecord behavior (possibly in conjunction with MySQL server) There is a huge table (hundreds millions entries) If I make this simple call:
SearchResult.where(id: ids[0..15000]).select('uid').to_a
...it will take less than 1 second.
Now if I make this call:
SearchResult.where(id: ids[0..16000]).select('uid').to_a
...it may take minutes!
While at the same time if I run the following two queries to get all 16k entries - it runs smoothly within 1 second total:
SearchResult.where(id: ids[0..15000]).select('uid').to_a +
SearchResult.where(id: ids[15001..16000]).select('uid').to_a
Moreover, if I call .to_sql on the long-running command and execute it directly via mysql command or MySQL Workbench - it takes even less than a second.
I ran ANALYZE TABLE and then tried EXPLAIN both directly and through ActiveRecord and they are identical. Both use ALL scan though (full table scan) The only difference is that it executes well directly, but hangs when executed through ActiveRecord. Now the fun thing - if I force use PRIMARY index - it starts working well through ActiveRecord, but that's not a solution because I can't use it with ActiveRecord associations preloading.
This weird behavior really stymies me because I'm using a lot of ActiveRecord associations preloading (eg. .includes(searches: :search_results)) which sometimes ends up requesting dozens of thousands records (yes, I do really need all of them), and such query stops execution for a good few minutes. I would just go with forced index use, but it does not resolve the problem in other places, creates more problems in others, and I won't be able to use ActiveRecord preloading then. Any ideas?
idsarray comprised of? It may make a lot more sense to rethink your query pattern to use a subquery or a range. AnArrayvalue will create anINclause, aRangevalue will create aBETWEENclause, and using a differentActiveRecord::Relationwill create a subquery.