【问题标题】:SQL joins and Subqueries , Subquery to SQL joinsSQL 连接和子查询,子查询到 SQL 连接
【发布时间】:2013-02-27 14:02:15
【问题描述】:

我写了这个 SQL 查询来获取不在邀请表中的用户的朋友,它会起作用,但是我读到子查询是性能消耗者,我对 JOINS 不是很好,任何帮助修改这个查询只是加入将不胜感激。

这是 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

任何帮助将不胜感激

【问题讨论】:

  • 如果您对性能有疑问,您也应该标记您正在使用的 RDBMS(例如 Oracle、SQL Server、MySQL)。 SQL 是声明性的。如何优化取决于您使用的产品。
  • 一个 JOIN 不一定可以重写为子选择。如果 DBMS 认为它会提高性能,它会自动执行此操作。
  • @a_horse_with_no_name 我正在使用 MySQL,它会这样做吗?
  • 不,MySQL 中的优化器非常愚蠢——尤其是子选择

标签: mysql sql performance join subquery


【解决方案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 解释了NOT INLEFT JOINNOT EXISTS(用于 SQL Server)之间的区别。因此,请测试这些不同的选项并为您的表格选择正确的选项。

【讨论】:

    【解决方案2】:

    您可以为此使用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
    

    【讨论】:

    • 如果您在搜索发生的列上正确定义了索引,那么您不必担心。这是来自一些链接的声明:LEFT JOIN / IS NULL and NOT EXISTS are semantically equivalent, while NOT IN is not.
    • 它与您的预期结果有何不同?
    猜你喜欢
    • 2023-03-29
    • 2020-09-27
    • 1970-01-01
    • 2013-09-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-20
    相关资源
    最近更新 更多