我有一个有效的查询,但它至少需要3秒才能运行,所以我认为它可能会更快。它用于填充新线程列表,并显示每个线程中有多少未读帖子。我在将查询字符串放入$db->query_read()
之前生成查询字符串。为了仅从有效论坛中获取结果,$ids
是最多50个以逗号分隔的值的字符串。
userthreadviews
表已存在1周,其中大约有9,500行。我不确定是否需要设置一个cron作业来定期清除超过一周的线程视图,或者我是否会好好让它成长。
以下是目前的查询:
SELECT
`thread`.`title` AS 'r_title',
`thread`.`threadid` AS 'r_threadid',
`thread`.`forumid` AS 'r_forumid',
`thread`.`lastposter` AS 'r_lastposter',
`thread`.`lastposterid` AS 'r_lastposterid',
`forum`.`title` AS 'f_title',
`thread`.`replycount` AS 'r_replycount',
`thread`.`lastpost` AS 'r_lastpost',
`userthreadviews`.`replycount` AS 'u_replycount',
`userthreadviews`.`id` AS 'u_id',
`thread`.`postusername` AS 'r_postusername',
`thread`.`postuserid` AS 'r_postuserid'
FROM
`thread`
INNER JOIN
`forum`
ON (`thread`.`forumid` = `forum`.`forumid`)
LEFT JOIN
(`userthreadviews`)
ON (`thread`.`threadid` = `userthreadviews`.`threadid`
AND `userthreadviews`.`userid`=$userid)
WHERE
`thread`.`forumid` IN($ids)
AND `thread`.`visible`=1
AND `thread`.`lastpost`> time() - 604800
ORDER BY `thread`.`lastpost` DESC LIMIT 0, 30
加入post
表的另一个查询(仅显示用户发布的帖子)的速度实际上是原来的两倍,所以我认为这里必须有一些可以改变以加速它的东西。有人可以提供一些建议吗?
编辑:对不起,我已将EXPLAIN放在备用查询的前面。这是正确的输出: 如同请求,这是EXPLAIN SELECT生成的输出:
答案 0 :(得分:2)
查看mysql explain声明。它为您提供查询的执行计划。
了解该计划后,您可以检查您是否获得了计划中涉及的字段的索引。如果没有,请创建它们。
也许该计划揭示了如何以另一种方式编写查询的详细信息,以便更加优化查询。
答案 1 :(得分:1)
如果没有编入索引,请尝试索引表forumid
答案 2 :(得分:1)
要在连接/ where上没有索引(在解释时使用key = NULL),这就是你的查询速度慢的原因。您应该以这样的方式索引它们:
CREATE INDEX thread_forumid_index ON thread(forumid);
CREATE INDEX userthreadviews_forumid_index ON userthreadviews(forumid);
文档here
答案 3 :(得分:0)
建议:
以下是我对查询的建议:
SELECT
`thread`.`title` AS 'r_title',
`thread`.`threadid` AS 'r_threadid',
`thread`.`forumid` AS 'r_forumid',
`thread`.`lastposter` AS 'r_lastposter',
`thread`.`lastposterid` AS 'r_lastposterid',
`forum`.`title` AS 'f_title',
`thread`.`replycount` AS 'r_replycount',
`thread`.`lastpost` AS 'r_lastpost',
`userthreadviews`.`replycount` AS 'u_replycount',
`userthreadviews`.`id` AS 'u_id',
`thread`.`postusername` AS 'r_postusername',
`thread`.`postuserid` AS 'r_postuserid'
FROM
`thread`
INNER JOIN (`forum`)
ON ((`thread`.`visible` = 1)
AND (`thread`.`lastpost` > $time)
AND (`thread`.`forumid` IN ($ids))
AND (`thread`.`forumid` = `forum`.`forumid`))
LEFT JOIN (`userthreadviews`)
ON ((`thread`.`threadid` = `userthreadviews`.`threadid`)
AND (`userthreadviews`.`userid` = $userid))
ORDER BY
`thread`.`lastpost` DESC
LIMIT
0, 30
这些是被编入索引的好候选人:
- `forum`.`forumid`
- `userthreadviews`.`threadid`
- `userthreadviews`.`userid`
- `thread`.`forumid`
- `thread`.`threadid`
- `thread`.`visible`
- `thread`.`lastpost`
看来你已经拥有了很多索引......所以,请确保保留你真正需要的索引并删除无用的索引。