Reputation: 8059
We have a table:
create table ducks (id int(8) primary key not null auto_increment,
name varchar(255),
car varchar(255),
money int(8)
);
insert into ducks set name='donald', car='none', money=10;
insert into ducks set name='scrudge', car='bip', money=10000;
insert into ducks set name='mac', car='bip', money=1000;
insert into ducks set name='joe', car='boo', money=2000000;
So analizing this I found that we got slow queries on the following request:
select name,money from ducks where car='bip' order by money DESC LIMIT 1;
because table is big and sorting just to get one record is very long
I found that the following works faster:
select distinct name,money from ducks where money=(select max(money) from ducks where car='bip') LIMIT 1;
but still not sure, because it is subselects.
what is common way to solve this ?
http://sqlfiddle.com/#!2/d2b7ed/6
update it turned that in reality we have a task to not searching same car but search richest duck which have less than $100000
http://sqlfiddle.com/#!2/d2b7ed/21
Upvotes: 1
Views: 211
Reputation: 169494
You are wise to be wary of subqueries; especially in MySQL.
The following query uses a self-exclusion join, and in basic testing performs the best of the three. Your first solution is fine, but as you say slow. It is also not ANSI-compliant, but that may not matter to you. Your second solution is also fine, but MySQL does not handle subqueries as well as might be hoped; at least traditionally.
select
d.name, d.money
from
ducks d
left join ducks d2
on d2.car = d.car
and d2.money > d.money
where
d.car = 'bip'
and d2.id is null
Implemented here: http://sqlfiddle.com/#!2/27711/20
Edit: The goalposts somehow moved. Darn those goalposts. This is the self-exclusion join solution for the new problem: http://sqlfiddle.com/#!2/7146d/13
select
d.name, d.money
from
ducks d
left join ducks d2
on d2.money > d.money
and d2.money < 100000
where
d.money < 100000
and d2.id is null;
Upvotes: 1