Для этого сайта мы работаем над этим, мы пытаемся получить самые популярные темы (в зависимости от того, сколько сообщений было сделано в них за последние 24 часа). У нас есть форум от среднего до большого, и текущий запрос MySQL выглядит так:
SELECT `forums_topics`.`id`,`forums_topics`.`name`,
(
SELECT COUNT(`id`)
FROM `forums_posts`
WHERE `postdate` > (UNIX_TIMESTAMP()-60*60*24)
AND `topicid`=`forums_topics`.`id`
) AS `trendy_threads`
FROM `forums_topics`
WHERE `deleted`=0
AND `lastpost` > (UNIX_TIMESTAMP()-60*60*24)
ORDER BY `trendy_threads` DESC,`postdate` DESC
LIMIT 3
SQL довольно вялый.
Как мы можем получить эту информацию как можно быстрее и эффективнее?
forums_topics
Field Type Null Key Default Extra
id int(50) NO PRI NULL auto_increment
uid varchar(255) NO NULL
flag int(1) NO 0
boardid varchar(255) NO NULL
postdate varchar(255) NO NULL
lastpost bigint(255) NO NULL
name varchar(50) NO NULL
description text NO NULL
body text NO NULL
author varchar(25) NO NULL
deleted tinyint(3) unsigned NO 0
deletememberid int(10) unsigned NO 0
pinned tinyint(1) NO 0
flagged text NO NULL
privateaccess text NO NULL
lastposter int(255) NO 1
replycount int(255) NO 0
viewcount int(255) NO 0
movedfrom int(255) NO 0
forums_posts
Field Type Null Key Default Extra
id int(50) NO PRI NULL auto_increment
topicid int(10) unsigned NO 0
author varchar(25) NO NULL
postdate varchar(255) NO NULL
body text NO NULL
lastedit varchar(255) NO NULL
postcount tinyint(1) NO NULL
invincible tinyint(1) NO 0
deleted tinyint(3) unsigned NO 0
deletememberid int(10) unsigned NO 0
thumbsup int(255) NO 0
thumbsdown int(255) NO 0
thumbsupuser text NO NULL
thumbsdownuser text NO NULL
Вероятно, проблема заключается в том, что MySQL оценивает подзапрос для каждой строки. Вы можете дать MySQL указание, что он должен выполнить подзапрос только один раз, переместив подзапрос в соединение:
SELECT *
FROM forum_topics ft
JOIN (
SELECT topicid
, COUNT(*) as cnt
FROM forums_posts
WHERE postdate > UNIX_TIMESTAMP()-60*60*24
GROUP BY
topicid
) fpc
ON ft.topicid = fpc.topicid
WHERE ft.deleted = 0
ORDER BY
fpc.cnt DESC
, ft.postdate DESC
LIMIT 3
Индекс на forum_posts(postdate, topicid)
еще больше повысит производительность.
Я собираюсь сделать удар в темноте, и при необходимости отредактирую дальше. Запрос EXPLAIN поможет.
SELECT `forums_topics`.*
FROM (
SELECT `topicid`, COUNT(*) as num
FROM `forums_posts`
WHERE `postdate` > (UNIX_TIMESTAMP()-60*60*24)
GROUP BY `topicid`
ORDER BY num DESC, `postdate` DESC
LIMIT 3
) `trendy`
LEFT JOIN `forums_topics` ON `id`=`topicid`
WHERE `deleted`=0
EXPLAIN {the query you posted}
?