我论坛的索引页面如下:
| 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`
您如何加快此查询?子查询的任何替代方案?
提前致谢!
答案 0 :(得分:2)
了解SQL joins和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
(如果您创建了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
你可以通过在主要选择中而不是在子选择中进行其中一个计数来改善这一点(但是周五晚了,我累了!)。