简体   繁体   中英

Suggestions on how I can optimize this MySQL query to run faster

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')

The query above is taking nearly 4 seconds to execute in MySQL and I want to know if anyone has any suggestions on how I might improve/optimize it to achieve a faster execution time?

Replace the in clauses with joins. I think the following captures the logic. Note that the not in turns into a left join with a condition in the where clause finding a non-match

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;

This looks similar but you have less nested queries.

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) )

This is the logic I reversed-engineered from your code without seeing tables.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM