简体   繁体   中英

MySQL Subquery, Join and Rank Query - Why very slow?

My query takes forever to load with only 800+ rows in members and 5,100+ rows in members_points .

Is there a more efficient approach to this that I'm overlooking, or another way to write this query using MySQL 5.5.33?

*UPDATE: 5.5 is my localhost and 5.7 is live server. not seeing any noticeable difference.

Here is what i have so far - Thank you for your feedback

  $result = $conn->query("
  SELECT subquery.*, 
         @rank := @rank + 1 `rank`
  FROM (SELECT m.id, 
               m.Name,
               m.Column_1,
               m.Column_2,
               m.Column_3,
               SUM(m.id = mp.id_from) total_sent,
               SUM(m.id = mp.id_to) total_received,
               SUM(m.id = mp.id_from) - SUM(m.id = mp.id_to) `points`
        FROM members m
        INNER JOIN members_points mp
        WHERE Account_Active LIKE 'TRUE'
        GROUP BY m.id, 
                 m.Name) subquery, (SELECT @rank := 0) variable
  ORDER BY `points` DESC;
  ");
SELECT subquery.*, 
         @rank := @rank + 1 `rank`
  FROM (SELECT m.id, 
               m.Name,
               m.Column_1,
               m.Column_2,
               m.Column_3,
               SUM(m.id = mp.id_from) total_sent,
               SUM(m.id = mp.id_to) total_received,
               SUM(m.id = mp.id_from) - SUM(m.id = mp.id_to) `points`
        FROM members m
        INNER JOIN members_points mp
        WHERE Account_Active LIKE 'TRUE'
        GROUP BY m.id, 
                 m.Name) subquery, (SELECT @rank := 0) variable
  ORDER BY `points` DESC;
  ");

Start with the counts before doing any JOINs .

SELECT id_from, COUNT(*) AS from_ct FROM members_points GROUP BY 1
SELECT id_to,   COUNT(*) AS   to_ct FROM members_points GROUP BY 1

Then use those as subqueries and work outward.

There could be a problem if you do or don't want to include an active member chatting with an inactive member. How many rows in the tables?

Now see if this looks right for subquery :

SELECT m.id, 
           m.Name,
           m.Column_1,
           m.Column_2,
           m.Column_3,
           froms.from_ct total_sent,
           tos.to_ct     total_received,
           froms.from_ct - tos.to_ct `points`
    FROM members m
    JOIN ( SELECT id_from, COUNT(*) AS from_ct FROM members_points GROUP BY 1
         ) AS froms  ON froms.id_from = m.id
    JOIN ( SELECT id_to,   COUNT(*) AS   to_ct FROM members_points GROUP BY 1
         ) AS tos    ON tos.id_to = m.id
    JOIN members_points mp
    WHERE m.Account_Active = 'TRUE'
    GROUP BY m.id, 
             m.Name

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