2013-02-27 194 views
0

我写了这个SQL查询以获得不在邀请表中的用户的朋友,它的工作原理是,但是我读到子查询是性能食用者,我不是很擅长连接,任何帮助修改这个查询只是在连接将非常感激。SQL连接和子查询,子查询到SQL连接

这里是SQL查询

SELECT friend.id, 
     friend.first_name 
FROM friends AS friend 
     INNER JOIN friends_users AS friendsUser 
     ON (friend.id = friendsUser.friend_id 
       AND friend.id NOT IN (SELECT friend_id 
            FROM friends_invitations 
            WHERE friends_invitations.user_id = 1)) 
ORDER BY friendsUser.id ASC 

这里是表结构

friends 
id   first_name 

friends_users 
id  friend_id  user_id 

friends_invitations 
id  friend_id user_id 

任何帮助将是非常赞赏

+1

如果您有关于性能的问题,应该标记您正在使用的RDBMS(例如Oracle,SQL Server,MySQL)。 SQL是声明式的。它如何进行优化取决于您使用的产品。 – 2013-02-27 14:09:18

+0

JOIN不一定会被重写为子选择。而一个具有体面优化器的数据库管理系统如果认为它可以提高性能,就会自动执行该操作。 – 2013-02-27 14:17:39

+0

@a_horse_with_no_name我使用的是MySQL吗? – Sedz 2013-02-27 14:20:16

回答

0

您可以使用LEFT JOIN为此,

SELECT friend.id, 
     friend.first_name 
FROM friends AS friend 
     INNER JOIN friends_users AS friendsUser 
      ON friend.id = friendsUser.friend_id 
     LEFT JOIN friends_invitations 
      ON friend.id = friends_invitations.friend_id AND 
       friends_invitations.user_id = 1 
WHERE friends_invitations.friend_id IS NULL 
ORDER BY friendsUser.id ASC 
+0

以及性能 – Sedz 2013-02-27 14:11:19

+0

(如果您已在搜索发生的列上正确定义索引的情况下),那么您不必担心。下面是一些链接的声明:'LEFT JOIN/IS NULL和NOT EXISTS在语义上是等价的,而NOT IN不是.' – 2013-02-27 14:16:29

+0

它不能正常工作 – Sedz 2013-02-27 14:22:39

1

子查询不一定是性能食用者,你的查询是否存在性能问题?总之,大多数时间做你的查询以最快的方式将使用NOT EXISTS

SELECT friend.id, 
     friend.first_name 
FROM friends AS friend 
INNER JOIN friends_users AS friendsUser 
    ON friend.id = friendsUser.friend_id 
WHERE NOT EXISTS (SELECT 1 FROM friends_invitations 
        WHERE friends_invitations.user_id = 1 
        AND friend_id = friend.id) 
ORDER BY friendsUser.id ASC 

Here is a link解释(用于SQL Server)NOT INLEFT JOINNOT EXISTS之间的差异。因此,测试这个不同的选项并为您的表选择正确的选项。