MySQL:如何加快这个查询(包括子查询)?

时间:2012-11-30 16:51:35

标签: mysql subquery database-performance

我论坛的索引页面如下:

| Forum   | Topics | Answers |
 ----------------------------
| Forum A | 123    | 45678   | 
| Forum B | 345    | 23128   |
| Forum C | 567    |  2328   | 

这是我的SQL代码到目前为止,但我认为必须有一个更好的解决方案:

SELECT f.`id`, f.`name`, f.`description`, f.`type`, 

      (SELECT COUNT(`id`) 
         FROM threads 
        WHERE `forum_id` = f.`id`) AS num_threads, 

      (SELECT COUNT(p.`id`) 
         FROM threads t, posts p 
        WHERE p.thread_id = t.id 
          AND t.forum_id = f.id) AS num_posts 

  FROM `forums` f ORDER BY `position`

您如何加快此查询?子查询的任何替代方案?

提前致谢!

2 个答案:

答案 0 :(得分:2)

了解SQL joinsGROUP BY

SELECT   f.id, f.name, f.description, f.type, 
         COUNT(DISTINCT t.id) AS num_threads,
         COUNT(*) AS num_posts
FROM     forums f
    JOIN threads t ON  t.forum_id = f.id
    JOIN posts   p ON p.thread_id = t.id
GROUP BY f.id
ORDER BY f.position

另外,请确保您拥有以下索引:

  • (id) forums
  • (id, forum_id) threads
  • (thread_id) posts

(如果您创建了foreign key contraints,MySQL将要求您拥有这些索引。)

答案 1 :(得分:2)

像这样的东西,加入带有group by子句的几个子查询的基本选择(因此它们每个执行一次,而不是每行执行一次)

  SELECT f.id, f.name, f.description, f.type, tc.RowCnt, ta.RowCnt
  FROM `forums` f 
  INNER JOIN (SELECT forum_id, COUNT(id) AS RowCnt FROM threads GROUP BY forum_id) tc
  INNER JOIN (SELECT forum_id, COUNT(p.id) AS RowCnt FROM threads t INNER JOIN posts p ON p.thread_id = t.id GROUP BY forum_id) ta
  ORDER BY position

你可以通过在主要选择中而不是在子选择中进行其中一个计数来改善这一点(但是周五晚了,我累了!)。