0

私のフォーラムのインデックスページは次のようになります。

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

このクエリをどのように高速化しますか?サブクエリの代替手段はありますか?

前もって感謝します!

4

2 に答える 2

2

SQL結合について学び、GROUP 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

(MySQLでは、外部キー制約を作成した場合、これらのインデックスが必要になります)。

于 2012-11-30T16:55:08.117 に答える
2

このようなもので、group by句を使用していくつかのサブクエリで基本的なselectを結合します(したがって、行ごとに1回ではなく、1回ずつ実行されます)

  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

サブセレクトではなくメインセレクトでカウントの1つを実行することで、これを改善できる可能性があります(ただし、金曜日は遅く、疲れています!)。

于 2012-11-30T16:57:52.467 に答える