【发布时间】:2013-02-04 05:04:39
【问题描述】:
我希望以某种方式加快此查询的速度。可能达到在低流量站点上运行它可以接受的程度。它需要 15 秒以上,这太长了。
目前表中有 13k 行,大约是 1 个月的数据,但我预计一旦网站投入使用,每月数据会翻倍。目的是选择上周的前 10 名收益。
有两个表,users 表和 tracker 表,tracker 表中每个用户有多行,每个用户每天至少 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 |
+----+----------------------+---------+-------+---------------+---------+---------+------------------+-------+----------------------------------------------+
【问题讨论】:
-
编辑您的帖子以添加
explain query select ...的输出,我将研究如何优化它。 -
已包含解释输出
-
你能以任何方式、形状或形式消除子查询吗?
-
在过去一天左右的时间里,我已经对此进行了一些调查,但是我无法理解它。根据我的发现,它应该有可能通过加入来实现
-
您不需要 2 个子查询,一个就足够了。在您获得他上周拥有的 exp 的子查询中,您可以进行减法,因为您还拥有用户拥有的最后一个 exp。
标签: mysql performance optimization