我希望以某种方式加快这个查询。可能达到在低流量站点上运行它可以接受的程度。它需要 15 秒以上,这太长了。
目前表中有 13k 行,大约是 1 个月的数据,但是我预计一旦网站投入使用,每月的数据会翻倍。目的是选择上周的前 10 名收益。
有两个表,用户表和跟踪器表,在跟踪器表中,每个用户有多行,每个用户每天至少 8 行。
查询的目的是获取每个用户的最新行,然后从 1 周前插入的行中减去一个值,以获得他们获得的 xp 数量,然后选择前 10 名获得最高收益的人。
表模式(我肯定也可以改进)
用户表
id int(11) primary
rsn varchar(12) unique
joined timestamp
disabled bool
跟踪表
id int(11) primary
user_id int(11) index /* Associated with the id in the users table */
timestamp timestamp
overall_rank int(11)
overall_level int(4)
overall_exp int(10)
和查询。
SELECT `users`.`rsn` , `tracker`.`timestamp` , @uid := `tracker`.`user_id` , (
SELECT `overall_exp`
FROM `tracker`
WHERE `user_id` = @uid
ORDER BY `timestamp` DESC
LIMIT 1
) - (
SELECT `overall_exp`
FROM `tracker`
WHERE `timestamp` >= SUBDATE( NOW( ) , INTERVAL 1 WEEK )
AND `user_id` = @uid
ORDER BY `timestamp` ASC
LIMIT 1 ) AS `gained_exp`
FROM `tracker`
JOIN `users` ON `tracker`.`user_id` = `users`.`id`
ORDER BY `gained_exp` DESC
LIMIT 10
解释输出
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+
| 1 | PRIMARY | users | index | PRIMARY | rsn | 14 | NULL | 71 | Using index; Using temporary; Using filesort |
| 1 | PRIMARY | tracker | ref | user_id | user_id | 4 | surreal.users.id | 103 | |
| 3 | UNCACHEABLE SUBQUERY | tracker | ALL | NULL | NULL | NULL | NULL | 11752 | Using where; Using filesort |
| 2 | UNCACHEABLE SUBQUERY | tracker | ALL | NULL | NULL | NULL | NULL | 11752 | Using where; Using filesort |
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+