MySQL多表Join优化案例

相关概念:MySQL

多表 JOIN + GROUP BY + COUNT(DISTINCT ...) 这种查询,最容易在“逻辑正确”之后暴露出性能问题。

场景

一个典型例子是:

  • player
  • owned_game
  • friend

要统计“当前用户与每个好友的共同游戏数,以及共同游戏占各自游戏总数的比例”。

第一个版本的问题

最直接的写法通常会把几张表一次性全连起来,再在外层聚合。

这种写法的问题不是“不对”,而是:

  • 中间结果集容易变大
  • GROUP BYCOUNT(DISTINCT ...) 成本高
  • 容易出现临时表和排序

原始执行结果从分钟级下降到几十秒,已经说明主要瓶颈不在“索引有没有”,而在“中间数据是不是太大”。

优化方向

先把真正需要的小结果集裁出来,再参与联接。

例如先限定“当前用户的游戏集合”,再去关联好友的游戏集合,而不是让所有 owned_game 一开始就直接冲进大聚合里。

这类 SQL 的判断顺序

遇到类似问题时,可以先问 3 件事:

  • 能不能先缩小参与连接的数据集
  • GROUP BY 前的中间行数是不是已经失控
  • 现有联合索引是否和真实连接路径一致

结论

复杂聚合 SQL 的优化,往往不是“把语句写得更花”,而是想办法让数据库更早看到更小的数据集。