2014-11-05 65 views
0
SELECT DISTINCT a.value 
FROM a LEFT JOIN b 
    ON a.value = b.value 
     AND (b.field IS NULL OR b.field != 'my_string'); 

SELECT a.value 
FROM a 
WHERE a.value NOT IN 
    (SELECT value 
    FROM b 
    WHERE b.field = 'my_string'); 

从我读过的内容中,做一个左连接更快。但我也读过DISTINCT是低效查询的代码异味。如何确定哪种查询在最坏情况下性能更好?选择不在另一个表中的行

编辑:对不起,id不是主键,它只是另一个字段。我会用价值取代它。

EDIT2:看起来每个人都挂了我的第一个查询。我们假设它看起来像这样。逻辑不一样吗?

SELECT DISTINCT a.value 
FROM a LEFT JOIN b ON a.value = b.value 
WHERE (b.field IS NULL OR b.field != 'my_string'); 

EDIT3:样品小提琴。 http://sqlfiddle.com/#!2/500ea/1

EDIT4:接受的答案。 http://sqlfiddle.com/#!2/500ea/8

回答

6

你的第一次加入是不合情理的。它将返回a中的所有a.id值。请记住,left join保留第一个表中的所有行,并在第二个表中匹配行。我想,你打算:

SELECT a.id 
FROM a LEFT JOIN 
    b 
    ON a.id = b.id AND b.field = 'my_string' 
WHERE b.field IS NULL; 

distinct应该是不必要的,假设a.id,没错,是一个唯一的ID。

一种替代方法是使用not exists

SELECT a.id 
FROM a 
WHERE NOT EXISTS (SELECT 1 FROM b WHERE a.id = b.id AND b.field = 'my_string'); 

出于性能上b(id, field)创建索引。

+0

忍者在写同样的回复+1 – 2014-11-05 23:27:27

+0

你说得对。谢谢。 http://sqlfiddle.com/#!2/500ea/8 – Tuan 2014-11-06 00:20:09

0

一般来说,NOT IN (SELECT ...)LEFT JOIN更inneficient,因为在IN()条件SELECT必须按顺序执行所述过滤器一次每一行执行。对于小数据集,这不是问题,但对于大型数据集,这可能是一个非常头痛的问题,相当不利。

相关问题