MySQL存在/进入/加入的最佳方式

时间:2013-12-23 21:38:49

标签: mysql

我不确定这样做的最好方法。我试图获得特定订阅的所有联系人,但是如果他们的用户订阅了其他订阅。

以下是获取具有特定订阅的用户的查询:

SELECT a.* FROM portal_contacts a
                    INNER JOIN portal_subscriptions_rel b
                        ON a.id=b.contactid
                     INNER JOIN portal_users c
                        ON c.id=a.user_id 
                     WHERE (b.subscription_id='1' OR b.subscription_id='3') 

但我想添加类似的内容:

AND (c.user_id IN (SELECT user_id FROM portal_subscriptions_rel WHERE subscription_id='5') OR c.user_id IN (SELECT user_id FROM portal_subscriptions_rel WHERE subscription_id='6'))

只是想知道最快的方法是什么。


修改1 好的,所以我将IN查询更改为:

AND (EXISTS (SELECT id FROM portal_subscriptions_rel WHERE user_id=c.id AND subscription_id='5') OR EXISTS (SELECT id FROM portal_subscriptions_rel WHERE user_id=c.id AND subscription_id='6'))

还有什么更快的吗?

2 个答案:

答案 0 :(得分:1)

您应该将额外条件添加为内部联接:

SELECT a.*
FROM portal_contacts a INNER JOIN
     portal_subscriptions_rel b
     ON a.id=b.contactid INNER JOIN
     portal_users c
     ON c.id=a.user_id INNER JOIN
     portal_subscriptions_rel psr2
     on c.user_id = psr2.user_id and
        psr2.subscription_id = '5'
WHERE (b.subscription_id='1' OR b.subscription_id='3') ;

join通常是添加条件最安全的方式。 Exists也可以。并且,如果来自portal_subscriptions_rel的多行可以匹配条件,那将是更可取的。 IN在逻辑上等同于exists。但是,在最新版本的MySQL之前,优化器为这些查询制定了一个非常糟糕的计划。

答案 1 :(得分:0)

尝试这样的事情:

SELECT a.* FROM portal_contacts a
                    INNER JOIN portal_subscriptions_rel b
                        ON a.id=b.contactid
                     INNER JOIN portal_users c
                        ON c.id=a.user_id 
                     WHERE (b.subscription_id='1' OR b.subscription_id='3') 
                     AND c.user_id IN 
(SELECT user_id FROM portal_subscriptions_rel
WHERE subscription_id in(5,6,......,n-1,n))