在定制论坛上获得热门话题

时间:2010-06-08 22:32:16

标签: php sql mysql forum

对于我们正在努力的这个网站,我们正在尝试获取最受欢迎的主题(根据过去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     

2 个答案:

答案 0 :(得分:1)

我将在黑暗中进行刺伤,如果需要,我会进一步编辑。 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

答案 1 :(得分:1)

问题可能是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)上的索引可以进一步提升效果。