jlos
jlos

Reputation: 1050

MySQL order by makes query slow solved, but not sure why

I have the following query:

select *
from 
  `twitter_posts` 
where 
  `main_handle_id` in (
    select 
      `twitter`.`main_handle_id` 
    from 
      `users` 
      inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
      `users` LIKE 'foo'
  ) 
order by created_at

This query runs dramatically slow when the order by is used. The twitter_posts table has indexes on the created_at timestamp and on the main_handle_id column.

I used "explain" to see what the engine was planning on doing and noticed a filesort... which I was not expecting to see as an index exists on the twitter_posts table. After skimming through the various posts covering this on Stackoverflow and blogs, none of the examples worked for me. I had a hunch, that maybe, the sql optimizer got confused somehow with the nested select. So I wrapped the query and ordered the result of that by created_at:

select * (select *
from 
  `twitter_posts` 
where 
  `main_handle_id` in (
    select 
      `twitter`.`main_handle_id` 
    from 
      `users` 
      inner join `twitter` on `twitter`.`user_id` = `user`.`id` 
    where 
      `users` LIKE 'foo'
  ) 
)
order by created_at

Using explain on this one, DOES use the index to sort and returns the response in a fraction of what it takes with filesort. So I've "solved" my problem, but I don't understand why SQL would make a different choice based on the solution. As far as I can see, I'm just wrapping the result and ask everything of that result in a seemingly redundant statement...

Edit: I'm still unaware of why the optimizer started using the index on the created_at when using a redundant subquery, but in some cases it wasn't faster. I've now gone with the solution to add the statement "FORCE INDEX FOR ORDER BY created_at_index_name".

Upvotes: 2

Views: 399

Answers (1)

Rick James
Rick James

Reputation: 142296

Don't use IN ( SELECT ... ); convert that to a JOIN. Or maybe converting to EXISTS ( SELECT ... ) may optimize better.

Please provide the EXPLAINs. Even if they are both the same. Provide EXPLAIN FORMAT=JSON SELECT ... if your version has such.

If the Optimizer is confused by a nested query, why add another nesting??

Which table is users in?

You mention user.id, yet there is no user table in FROM or JOIN.

What version of MySQL (or MariaDB) are you using? 5.6 and especially 5.7 have significant differences in the optimizer, with respect to MariaDB.

Please provide SHOW CREATE TABLE for each table mentioned in the query.

There are hints in your comments that the queries you presented are not the ones giving you trouble. Please do not ask about a query that does not itself demonstrate the problem.

Oh, is it users.name? Need to see the CREATE TABLEs to see if you have a suitable index.

Since MariaDB was mentioned, I am adding that tag. (This is probably the only way to get someone with specific MariaDB expertise involved.)

Upvotes: 1

Related Questions