我有一个MySQL查询,如下所示
SELECT
count(`clicks`.`user_id`) as total,
`users`.`fullname`
FROM
`users`,
`clicks`,
WHERE
`users`.`id` = `clicks`.`user_id`
GROUP BY
`clicks`.`user_id`
ORDER BY
`total` desc
LIMIT
0,20;
我正在运行几款按键式游戏的统计数据。它有一个用户表和一个点击表。它记录来自特定用户的点击。用户可以随时单击按钮。一天二十次点击,三十次点击等等。它们并非全部连续。
目前,~2k用户的点击次数约为180k。此查询平均需要1.38秒。如果可能的话,我想加快速度。
答案 0 :(得分:1)
如果您将clicks.user_id和users.id列编入索引,那么该查询可能会尽可能快。
有一件事我可以想象要对很多迟缓负责,这就是ORDER BY子句。看到它是一个聚合字段,它可能必须首先获取所有数据,然后在没有太多优化的情况下对其进行排序。当任何事情都很缓慢时,排序是一个很好的选择。
另一个想法是,维护一个包含总点击次数的单独表格。如果您需要这些记录,那么您最终可能需要为每次点击运行2个查询...一个用于现有表,另一个用于更新用户/点击表,其中只有user_id和click_count以及您认为的任何其他内容是合适的。这样,SELECTs应该变得闪电般快,即使有很多很多用户,因为你只检索绝对必要的最小行数而不是一大堆那些然后只得到聚合的行。
答案 1 :(得分:1)
USERS.id
定义为表的主键?它应该是...... CLICKS.user_id
是否有外键约束将其值与USERS.id
相关联?USERS.id
和CLICKS.user_id
是数字数据类型(IE:INT),而不是基于文本的?CLICKS.user_id
USERS.fullname
如果存在索引,have you tried refreshes the table statistics:
ANALYZE TABLE USERS;
ANALYZE TABLE CLICKS;
答案 2 :(得分:0)
确保您已在users.id
和clicks.user_id
上创建了索引。您还可以在执行连接之前尝试计算点击次数,但我怀疑如果这实际上会提高性能,那么引擎无论如何都会为您执行此操作。
答案 3 :(得分:0)
为starters创建一个clicks.userid索引。这将有所作为
答案 4 :(得分:0)
试试这个(未经测试):
SELECT
C.total,
`users`.`fullname`
FROM
`users`
INNER JOIN
(SELECT COUNT(*) AS total, user_id
FROM
`clicks`
GROUP BY
`user_id`
ORDER BY
COUNT(*)
LIMIT 0,20) C
ON C.user_id = users.user_id
ORDER BY
C.total desc
首先计算行可能会节省一些时间。
答案 5 :(得分:0)
我只想到别的东西。使用INNER JOIN可能会获得更好的结果。
未测试:
SELECT
count(`clicks`.`user_id`) as total,
`users`.`fullname`
FROM
`users`
INNER JOIN `clicks` ON `clicks`.`user_id` = `users`.`id`
GROUP BY
`clicks`.`user_id`
ORDER BY
`total` desc
LIMIT
0,20;