2012-02-04 65 views
4

我希望这个问题没有被问到,我试图寻找类似的问题,但可能使用了错误的关键字。总之,我碰到一个情况,我必须寻找谁从来没有下订单的客户,所以在查询运行这样的:改善选择不在

SELECT * FROM customers 
where customers_id NOT IN (SELECT customers_id FROM orders) 

我看,这是不好的嵌套SELECT S,所以什么是更好的选择?

此外,我应该做select *还是应该指定字段,我还在某个地方看过,最好是select *

谢谢大家提前。

+0

看到的答案后,我有一个疑问EXISTS的优化。你可以请时间StilesCrisis和Joop Eggen的解决方案,看看哪一个跑得更快?感谢 – 2012-02-04 08:03:21

+1

矿:显示行0 - 29(5390总计,查询花费0.0155秒) StilesCrisis:显示行0 - 29(5390总计,查询花费0.0090秒) 乔普埃根:显示行0 - 29(5390总共查询花费0.0039秒) 注:我每跑一次,可能需要运行多次获得平均时间的权利。此外,对于乔普的一个我用SELECT *,想知道如果事情可以改善,如果我不与特定的字段 – mr1031011 2012-02-04 08:35:48

+1

选择不管你相信与否,之后多次运行乔普的答案仍然是在我的情况下更快。 – mr1031011 2012-02-04 08:39:36

回答

5
SELECT * FROM customers 
LEFT JOIN orders ON customers.customers_id = orders.customers_id 
WHERE orders.customers_id IS NULL 
+0

亲爱的StilesCrisis,谢谢你的答案,非常有趣的解决方案,从来没有想过它 – mr1031011 2012-02-04 08:46:03

2

容易的问题:SELECT *比选择一些领域更加昂贵,它可以是戏剧性的。数据较少,如果索引中的所有字段都没有表访问。没有从数据库字段值到编程语言变量的编组。

嵌套子查询和关节有他们的权利。

SELECT * 
FROM customers c 
WHERE NOT EXISTS(SELECT * 
       FROM orders o 
       WHERE o.customers_id = c.customers_id) 

MySQL的说,它可以更好地优化形式存在递归优化上c.customers_id选择现在拥有的信息:

SELECT * FROM customers where customers_id NOT IN (SELECT customers_id FROM orders) 

可以作为被改写。

虽然最好是@StilesCrisis的加入,但我怀疑它是正确的。 (虽然我一天没喝我的第一杯咖啡。)

顺便说一句。 EXISTS(SELECT *并不是真的为所有领域预留空间,并且没关系。

+1

不知道你为什么怀疑'JOIN'。这并不复杂。 – StilesCrisis 2012-02-04 07:50:10

+0

现在有一个** **加入对customers_id但你想去的地方存在_no_这样的匹配的客户。空检查不影响。是吗? NOOO你是对的。 – 2012-02-04 08:03:25

+0

@StilesCrisis也许'选择DISTINCT'?必须说,从来没有使用过你的图案,尽管类似的左侧关节 – 2012-02-04 08:17:23