在相关表上使用sum()时查询时间慢

时间:2019-04-19 13:17:47

标签: mysql sql

我有两个表(用户和xp_points)。我需要获取每个用户的xp点的总和。但是我的查询似乎非常慢(380毫秒)。我的数据库很大。我试图在用户表上创建一列称为total_xp_points的列,然后查询时间仅为4.6 ms。

但是我不想手动更新每个用户的总xp点。有没有一种方法可以优化此查询的速度?

用户表

+----+-------------+-----------------+
| id |  fullname   | total_xp_points |
+----+-------------+-----------------+
|  1 | John Adams  |              22 |
|  2 | Will Smith  |               0 |
|  3 | Bob McGee   |             125 |
|  4 | Andy Briggs |               0 |
|  5 | Linda James |              20 |
+----+-------------+-----------------+

xp_points表

+----+---------+------------+-----------+
| id | user_id |    date    | xp_points |
+----+---------+------------+-----------+
|  1 |       1 | 2019-01-05 |        17 |
|  2 |       1 | 2019-03-07 |         5 |
|  3 |       3 | 2019-03-07 |         0 |
|  4 |       3 | 2019-01-08 |       125 |
|  5 |       5 | 2019-01-19 |        20 |
+----+---------+------------+-----------+

此查询花费了 380.711毫秒(慢得多)

SELECT
    users.id as user_id,
    users.fullname,
    sum(xp_points.xp_points) AS total_xp_points
FROM
    users
INNER JOIN xp_points
    ON users.id = xp_points.user_id
GROUP BY
    user_id,
    users.fullname
HAVING
    SUM(xp_points.xp_points) > 3
LIMIT 100

结果

+---------+-------------+-----------------+
| user_id |  fullname   | total_xp_points |
+---------+-------------+-----------------+
|       1 | John Adams  |              22 |
|       3 | Bob McGee   |             125 |
|       5 | Linda James |              20 |
+---------+-------------+-----------------+

下一个查询仅需 4.641毫秒要快得多,但我必须在不需要的用户表上手动维护total_xp_points

SELECT
    users.id as user_id,
    fullname,
    total_xp_points
FROM users
WHERE
    total_xp_points > 3
limit 100

它的结果与第一次查询相同(但执行时间更快

+---------+-------------+-----------------+
| user_id |  fullname   | total_xp_points |
+---------+-------------+-----------------+
|       1 | John Adams  |              22 |
|       3 | Bob McGee   |             125 |
|       5 | Linda James |              20 |
+---------+-------------+-----------------+

1 个答案:

答案 0 :(得分:1)

部分问题可能是GROUP BY。您可以尝试选择一个子查询,如下所示:

SELECT users.id AS user_id,
       users.fullname,
       (SELECT SUM(xp_points) FROM xp_points WHERE xp_points.user_id = users.id) AS total_xp_points
  FROM users
HAVING total_xp_points > 3
 LIMIT 100