2012-10-11 51 views
1

我知道总有一种更好的方式来做某件事,但我不知道该怎么做?什么是优化此查询的最佳方法?我应该使用连接,单独的查询等。我知道这不是一个复杂的查询..只是想扩大我的知识。SubSelect or Joins?有没有更好的方式来编写这个mysql查询?

任何建议,将不胜感激!

SELECT 
    community_threads.id AS thread_id, 
    community_threads.title AS thread_title, 
    community_threads.date AS thread_date, 
    community_threads.author_id AS author_id, 
    `user`.display_name AS author_name, 
    `user`.organization AS author_organization, 
    (SELECT date FROM community_replies replies WHERE replies.thread_id = community_threads.id ORDER BY date DESC LIMIT 1) AS reply_date, 
    (SELECT count(id) FROM community_replies replies WHERE replies.thread_id = community_threads.id ORDER BY date DESC LIMIT 1) AS total_replies 
FROM 
    community_threads 
INNER JOIN `user` ON community_threads.author_id = `user`.id 
WHERE 
    category_id = '1' 
ORDER BY 
    reply_date DESC 
LIMIT 0, 5 

回答

1

这可以用JOIN针对子选择它获取每thread_id和骨料MAX(date)骨料COUNT()得到改善。除了对每行的子查询进行评估之外,对于整个查询,派生表只应计算一次,并与来自community_threads的其余行进行连接。

SELECT 
    community_threads.id AS thread_id, 
    community_threads.title AS thread_title, 
    community_threads.date AS thread_date, 
    community_threads.author_id AS author_id, 
    `user`.display_name AS author_name, 
    `user`.organization AS author_organization, 
    /* From the joined subqueries */ 
    maxdate.date AS reply_date, 
    threadcount.num AS total_replies 
FROM 
    community_threads 
    INNER JOIN `user` ON community_threads.author_id = `user`.id 
    /* JOIN against subqueries to return MAX(date) (same as order by date DESC limit 1) and COUNT(*) from replies */ 
    /* number of replies per thread_id */ 
    INNER JOIN (
    SELECT thread_id, COUNT(*) AS num FROM replies GROUP BY thread_id 
) threadcount ON community_threads.id = threadcount.thread_id 
    /* Most recent date per thread_id */ 
    INNER JOIN (
    SELECT thread_id, MAX(date) AS date FROM replies GROUP BY thread_id 
) maxdate ON community_threads.id = maxdate.thread_id 
WHERE 
    category_id = '1' 
ORDER BY 
    reply_date DESC 
LIMIT 0, 5 

如果你把LIMIT 0, 5reply_date子查询中你可能会得到更好的性能。那只会拉取子查询中最近的5个,并且INNER JOIN将会丢弃全部来自community_threads的不匹配。

/* I *think* this will work...*/ 
SELECT 
    community_threads.id AS thread_id, 
    community_threads.title AS thread_title, 
    community_threads.date AS thread_date, 
    community_threads.author_id AS author_id, 
    `user`.display_name AS author_name, 
    `user`.organization AS author_organization, 
    /* From the joined subqueries */ 
    maxdate.date AS reply_date, 
    threadcount.num AS total_replies 
FROM 
    community_threads 
    INNER JOIN `user` ON community_threads.author_id = `user`.id 
    INNER JOIN (
    SELECT thread_id, COUNT(*) AS num FROM replies GROUP BY thread_id 
) threadcount ON community_threads.id = threadcount.thread_id 
    /* LIMIT in this subquery */ 
    INNER JOIN (
    SELECT thread_id, MAX(date) AS date FROM replies GROUP BY thread_id ORDER BY date DESC LIMIT 0, 5 
) maxdate ON community_threads.id = maxdate.thread_id 
WHERE 
    category_id = '1' 
ORDER BY 
    reply_date DESC 
+0

有趣,谢谢..从来没有想过使用MIN/MAX之前。一旦我获得声望,我会投票。 – cire

0

尽我所知,这看起来像是一个群体的好机会。

SELECT 
    community_threads.id AS thread_id, 
    community_threads.title AS thread_title, 
    community_threads.date AS thread_date, 
    community_threads.author_id AS author_id, 
    `user`.display_name AS author_name, 
    `user`.organization AS author_organization, 
    MAX(replies.date) AS reply_date, 
    COUNT(replies.id) AS total_replies 
FROM community_threads 
INNER JOIN `user` ON community_threads.author_id = `user`.id 
INNER JOIN community_replies AS replies ON replies.thread_id = community_threads.id 
WHERE category_id = 1 
GROUP BY thread_id, thread_title, thread_date, author_id, author_name, author_organization) 
ORDER BY reply_date DESC 
LIMIT 0, 5 

希望这会有所帮助。

相关问题