Nie mogę sobie pozwolić na pobieranie wszystkich wierszy.
Ostatecznie skonstruowałem takie zapytanie:
SELECT F.ForumId, F.Name, COUNT(T.ThreadId) AS ThreadNum, SUM(T.PostNum) AS PostNum, T.ThreadId AS LastThreadId, T.Name AS LastThreadName, MAX(T.PostLastDate) AS PostLastDate, COUNT(T.ThreadId)-SUM(T.ThreadRead) AS UnreadPosts
FROM ForumsForums AS F
LEFT JOIN(
SELECT T.ThreadId, T.ForumId, T.Name, SUM(P.PostNum) AS PostNum, MAX(P.PostLastDate) AS PostLastDate, COUNT(V.ThreadId) AS ThreadRead
FROM ForumsThreads AS T
LEFT JOIN (
SELECT COUNT(PostId) AS PostNum, ThreadId, MAX(Date) AS PostLastDate
FROM ForumsPosts
WHERE Public=1
GROUP BY ThreadId
) AS P USING ( ThreadId )
LEFT JOIN ForumsThreadViews AS V ON (T.ThreadId=V.ThreadId AND V.UserId='%d' AND V.UnseenPostId = 0)
WHERE Public=1
GROUP BY ThreadId
ORDER BY PostLastDate DESC
) AS T ON(F.ForumId=T.ForumId)
WHERE F.Public=1 AND F.BoardId='%d'
GROUP BY F.ForumId
ORDER BY Sort ASC
Każda tabela ma PRIMARY na swoje Id (ForumsForums - ForumId) + klucz rodzica i te według których grupuję / sortuje / whereuje
EXPLAIN zapytania wywala:
Kod
1 PRIMARY F ref Public,BoardId BoardId 2 const 1 Using where; Using temporary; Using filesort
1 PRIMARY <derived2> ALL NULL NULL NULL NULL 4
2 DERIVED T ref Public Public 1 3 Using temporary; Using filesort
2 DERIVED <derived3> ALL NULL NULL NULL NULL 4
2 DERIVED V eq_ref PRIMARY,ThreadId,UserId PRIMARY 12 xxx.T.ThreadId 1
3 DERIVED ForumsPosts ALL Public NULL NULL NULL 46 Using where; Using temporary; Using filesort
Jestem rootem na serwerze, mam 16GB ramu do dyspozycji więc mogę zwiększyć jakoś wartości pamięci podręcznej itp.
Jeszcze trochę o typach danych
ForumId, ThreadId - INT
PostId, UserId - BIGINT
Public - BOOL
Date - TIMESTAMP
Teraz pytanie, jak to się zachowa przy 100k postów i 20k tematów. Czy nie zamuli serwera?
Może lepiej ilość postów przechowywać jako pole w tabeli nadrzędnej?