我们有一张桌子:
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;
所以分析这个我发现我们对以下请求的查询很慢:
select name,money from ducks where car='bip' order by money DESC LIMIT 1;
因为表很大而且排序只是为了得到一条记录很长
我发现以下内容更快:
select distinct name,money from ducks where money=(select max(money) from ducks where car='bip') LIMIT 1;
但仍然不确定,因为它是子选择。
解决这个问题的常用方法是什么?
http://sqlfiddle.com/#!2/d2b7ed/6
更新它转变为现实中我们的任务是不搜索同一辆车,但搜索价格低于100000美元的最富有的鸭子
答案 0 :(得分:1)
你明智地要警惕子查询;特别是在MySQL中。
以下查询使用自我排除联接,并且在基本测试中执行三者中最好的一个。你的第一个解决方案很好,但正如你说的慢。它也不符合ANSI标准,但这对您来说无关紧要。你的第二个解决方案也没问题,但是MySQL并没有像希望的那样处理子查询;至少传统上。
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
在这里实施:http://sqlfiddle.com/#!2/27711/20
编辑:球门柱以某种方式移动了。弄清楚那些球门柱。这是针对新问题的自我排除加入解决方案: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;