0
我正在寻找以某种方式加快此查询。可能达到可接受的程度,在低流量网站上运行它。这需要15+秒,这太长了。优化此mysql查询
目前表中有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
Explain输出
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+
| 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 |
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+
编辑您的文章添加'explain query select ...'的输出,我会研究如何优化它。 – hd1
已包括解释输出 – Wader
你可以消除子查询以任何方式,形状或形式? – hd1