Reputation: 1591
I have a 2 gb mysql table with 500k rows and I run the following query on a system with no load.
select * from mytable
where name in ('n1', 'n2', 'n3', 'n4', ... bunch more... )
order by salary
It takes a filesort and between 50 and 70 seconds to complete.
When removing the order by salary and doing the sorting in the application, the total runtime (including the sorting) cuts to about 25-30 seconds. But that's still far too much.
Any idea how I can speed this up?
Thank you.
Upvotes: 3
Views: 628
Reputation: 28730
Depending on the data distribution and the amount of rows your WHERE clause matches, you may want to try an index on (salary, name) or even (name, salary) although the latter will most probably not be very useful for that kind of queries.
You may also want to increase your sort_buffer_size setting. Test everything seperately and compare the output of EXPLAIN.
Upvotes: 1
Reputation:
Try selecting the rows you want using a subquery, and then order the results of that subquery. See this question.
And you do have an index on name
in mytable
, right?
Upvotes: 1
Reputation: 131112
Some ideas:
Upvotes: 1
Reputation: 35141
create index xyz on mytable(name(6));
"IN" queries are almost alway inefficient, as they are conceptually processed like this:
select * from mytable where name = n1
or name = n2
or name = n3
...
The index I've given above may mean the query optimizer accesses the rows by index instead of table scan.
Upvotes: 0
Reputation: 95093
Drop the list of names into a temporary table and then do an inner join on the two tables. This way is much faster than combing that entire list for each row. Here's the pseudocode:
create temporary table names
(name varchar(255));
insert into names values ('n1'),('n2'),...,('nn');
select
a.*
from
mytable a
inner join names b on
a.name = b.name
Also note that name
should have an index on it. That makes things go much faster. Thanks to Thomas for making this note.
Upvotes: 5