MySQL 子查询、连接和排名查询 - 为什么很慢?

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

我的查询需要永远加载 members 中的 800 多行和 members_points 中的 5,100 多行。

是否有我忽略的更有效的方法,或者使用 MySQL 5.5.33 编写此查询的另一种方法?

*更新:5.5 是我的本地主机,5.7 是实时服务器。没有看到任何明显的差异。

这是我目前的情况 - 感谢您的反馈

  $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;
  ");

在执行任何操作之前先从计数开始 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

然后将它们用作子查询并向外工作。

如果您想要或不想让 活跃 成员与 不活跃 成员聊天,可能会出现问题。表格中有多少行?

现在看看这是否适合 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