【问题标题】:Suggestions on how I can optimize this MySQL query to run faster关于如何优化此 MySQL 查询以更快运行的建议
【发布时间】:2013-09-19 22:58:36
【问题描述】:
SELECT * 
FROM   members 
WHERE  memberid IN (SELECT follows.followingid 
                    FROM   follows 
                    WHERE  follows.memberid = '$memberid' 
                           AND follows.followingid NOT IN (SELECT memberid 
                                                           FROM   userblock)) 
       AND memberid NOT IN (SELECT blockmemberid 
                            FROM   userblock 
                            WHERE  memberid = '$memberid')

上面的查询在 MySQL 中执行需要将近 4 秒,我想知道是否有人对我如何改进/优化它以实现更快的执行时间有任何建议?

【问题讨论】:

  • 我想问“为什么?”您能否详细说明此查询的逻辑?也许它应该被一个更好的完全取代。
  • 你使用什么版本的 MySQL? MySQL 在子查询优化方面很差。
  • @Malkocoglu 我正在尝试在“关注”表中搜索与其有关系的表中的值 memberid。然后我想过滤掉用户块表中出现这种关系的任何值。
  • @zavg 我使用的是 MySQL 5.5.30 版
  • 我认为有一个逻辑问题。你是如何使用用户块表的?是 userblock.memberid 是阻止别人的人吗?而 userblock.blockmemberid 就是被屏蔽的人。

标签: mysql optimization


【解决方案1】:

用连接替换in 子句。我认为以下内容抓住了逻辑。请注意,not in 会变成 left join,并在 where 子句中找到不匹配的条件

SELECT m.* 
FROM members m
     follow f
     on m.memberid = f.followingid and 
        f.memberid = $memberid left join
     userblock ubf
     on follows.followingid = ubf.memberid left join
     userblock ub
     on m.memberid = ub.blockmemberid and
        ub.memberid = '$memberid'
where ub.blockmemberid is null and
      ubf.memberid is null;

【讨论】:

    【解决方案2】:

    这看起来很相似,但嵌套查询更少。

    SELECT * 
    FROM   members m
    WHERE  EXIST (SELECT f.followingid 
                  FROM   follows f
                  WHERE  f.memberid = '$memberid'
                         AND f.followingid = m.memberid)
    
           AND NOT EXIST (SELECT u.blockmemberid 
                          FROM   userblock u
                          WHERE  (m.memberid = '$memberid'
                                 AND u.blockmemberid = m.memberid)
                              OR 
                                 (u.blockmemberid = m.memberid
                                 AND u.memberid = m.memberid) )
    

    这是我在没有看到表格的情况下从您的代码逆向工程的逻辑。

    【讨论】:

      【解决方案3】:
      SELECT m.* 
      FROM   members m
      INNER JOIN follows f ON f.followingid = m.memberid AND
                              f.memberid = '$memberid'
      LEFT OUTER JOIN userblock ub1 ON f.followingid = ub1.memberid 
      LEFT OUTER JOIN userblock ub2 ON m.memberid = ub2.blockmemberid AND
                                  ub2.memberid = '$memberid'
      WHERE ub1.memberid IS NULL AND ub2.blockmemberid IS NULL
      

      【讨论】:

        猜你喜欢
        • 2016-02-27
        • 1970-01-01
        • 2012-06-27
        • 1970-01-01
        • 2021-11-11
        • 2015-05-22
        • 2023-04-01
        • 2014-02-17
        • 1970-01-01
        相关资源
        最近更新 更多