Получение популярных тем на форуме по индивидуальному заказу - PullRequest
0 голосов
/ 09 июня 2010

Для этого веб-сайта, над которым мы работаем, мы пытаемся получить самые популярные темы (основываясь на том, сколько сообщений было сделано в них за последние 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 ]

1 голос
/ 09 июня 2010

Проблема, вероятно, в том, что 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) еще больше улучшит производительность.

1 голос
/ 09 июня 2010

Я собираюсь сделать удар в темноте, и я буду редактировать дальше, если это необходимо.Разъяснение запроса поможет.

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
...