MySQL 查询永远加载

MySQL query loads forever

我有一个 table 的 1v1 比赛是这样的:

match_number|winner_id|loser_id
------------+---------+--------
     1      |   1     |   2
     2      |   2     |   3
     3      |   1     |   2
     4      |   1     |   4
     5      |   4     |   1

我想得到这样的东西:

player|matches_won|matches_lost
------+-----------+------------
  1   |     3     |     1
  2   |     1     |     2
  3   |     0     |     1
  4   |     1     |     1

我的 MySQL 查询如下所示

SELECT win_matches."winner_id" player, COUNT(win_matches."winner_id") matches_won, COUNT(lost_matches."loser_id") matches_lost FROM `matches` win_matches
JOIN `matches` lost_matches ON win_matches."winner_id" = lost_matches."winner_id"

我不知道我做错了什么,但查询只是永远加载并且 return 没有任何内容

您想先逆轴再聚合:

select player_id, sum(is_win), sum(is_loss)
from ((select winner_id as player_id 1 as is_win, 0 as is_loss
       from t
      ) union all
      (select loser_id, 0, 1
       from t
      ) 
     ) wl
group by player_id;

您的查询根本不正确。这两个计数将产生相同的值——COUNT(<expression>) returns 该表达式的非 NULL 行数。你的两个计数 return 是一样的。

一直拖延的原因是笛卡尔积问题。如果一个玩家赢了 10 场,输了 10 场,那么您的查询会产生 100 行——对于玩得更频繁的玩家来说,情况会更糟。处理所有这些额外的行需要时间。

如果你有单独的playerstable,那么关联子查询可能是最快的方法:

select p.*,
       (select count(*) from t where t.winner_id = p.player_id) as num_wins,
       (select count(*) from t where t.loser_id = p.player_id) as num_loses
from players p;

但是,这需要两个指标来提高 (winner_id)(loser_id) 的性能。请注意,这些是单独的索引,而不是单个复合索引。

您将加入同一个 table 两次。

别名 win_matcheslost_matches 都在 table matches 上,导致循环。

您可能不需要单独的 table 来表示输赢,并且可以在相同的 table 中通过在每列中写一个或零来实现。

我不想对你的模型做太多改变,让它难以理解,所以这里稍微修改一下,它看起来像:

SELECT  m."player_id" player, 
    SUM(m."win") matches_won, 
    SUM(m."loss") matches_lost 
FROM `matches` m
GROUP BY player_id

没有连接,全部在同一个 table 中,有输赢列。在我看来,您想知道每个玩家的输赢次数,这可以通过玩家分组和 sum/count.

来实现