webForumDet fria alternativet

Endast ett inlägg/en tråd skall redovisas

Databaser & SQL

4 svar · 265 visningar · startad av ampy

Medlem sedan feb. 20011 498 inlägg
Frågan#1

Har denna sql-fråga:

SELECT 
	ft.threadID, 
	ft.subject, 
	ft.userid, 
	m1.usr, 
	ft.room, 
	ft.last_post, 
	ft.readers, 
	ft.answers, 
	ft.smiley, 
	fp.id, 
	fp.userid, 
	fp.datum, 
	m2.usr, 
	ft.poll, 
	ft.locked 
FROM
	forum_topics ft 
	inner join forum_posts fp on fp.threadID = ft.threadID 
	inner join members m1 on ft.userid = m1.id 
	inner join members m2 on m2.id = fp.userid 
WHERE 
	fp.userid = 1 
ORDER BY
	ft.room asc, ft.last_post desc limit 0,20

Problem 1
Frågan är en del av en söktjänst till ett forum. Vad frågan ovan gör är att den "söker" igenom alla inlägg som är skrivna av användaren som har ID-nummer 1 (se WHERE-klausulen).

Problemet är det att användaren i fråga kan ha skrivit fler än ett inlägg i en tråd. Om så är fallet kommer utskriften att resultera i att en tråd skrivs ut flera gånger (det antalet gånger användaren har skrivit i tråden).

Jag har provat med att sätta distinct på ft.threadID med det hjälpte inte.

Problem 2
För tillfället har jag ännu en sql-fråga i självaste iteratorn som hämtar det senaste inlägget i aktuell tråd. Det är inget vidare att ha en sql-fråga i en iterator (loop) så därför vill jag inkludera denna fråga i huvudfrågan.
Därför måste huvudfrågan formuleras sådan att den, tillsammans med tråden, hämtar det senaste inlägget i tråden (fp.id desc).

Har testat med att lägga till HAVING-klausulen:

having ft.last_post = max(fp.datum)

Men detta resulterade i noll träffar/trådar, antagligen för att användaren i fråga inte har skrivit det senaste inlägget.

Är det någon som kan fundera på hur denna 'stora' sql-fråga skall formuleras?

Tacksam för svar.

Medlem sedan dec. 200012 464 inlägg
#2
SELECT 
	ft.threadID, 
	ft.subject, 
	ft.userid, 
	m1.usr, 
	ft.room, 
	ft.last_post, 
	ft.readers, 
	ft.answers, 
	ft.smiley, 
	fp.id, 
	fp.userid, 
	fp.datum, 
	m2.usr, 
	ft.poll, 
	ft.locked 
FROM
	forum_topics ft 
	inner join forum_posts fp on fp.threadID = ft.threadID 
	inner join members m1 on ft.userid = m1.id 
	inner join members m2 on m2.id = fp.userid 
        inner join forum_posts fp2 on fp2.threadID = ft.threadID 
WHERE 
	fp.userid = 1 
        group by ft.threadID, 
	ft.subject, 
	ft.userid, 
	m1.usr, 
	ft.room, 
	ft.last_post, 
	ft.readers, 
	ft.answers, 
	ft.smiley, 
	fp.id, 
	fp.userid, 
	fp.datum, 
	m2.usr, 
	ft.poll, 
	ft.locked 
having fp.datum = min(fp2.datum)
ORDER BY
	ft.room asc, ft.last_post desc limit 0,20

Samma teknik på fråga 2.

Medlem sedan feb. 20011 498 inlägg
#3

SQL-frågan fungerar som jag hade tänkt, men den är otroligt seg när det handlar om många poster.

T.ex. när man söker på användar-id 1:s inlägg, låt oss kalla 1 för Uffe, får man 650 träffar/trådar.

Uffe har alltså skrivit i 650 trådar. Om man räknar i inlägg blir det 2170 stycken (tabell forum_posts).

Kan man inte optimera frågan lite?

Indexerade kolumner är markerade i fetstil:

SELECT 
	[b]ft.threadID[/b], 
	[b]ft.subject[/b], 
	[b]ft.userid[/b], 
	[b]m1.usr[/b], 
	[b]ft.room[/b], 
	[b]ft.last_post[/b], 
	ft.readers, 
	ft.answers, 
	ft.smiley, 
	[b]fp.id[/b], 
	[b]fp.userid[/b], 
	[b]fp.datum[/b], 
	[b]m2.usr[/b], 
	ft.poll, 
	ft.locked 
FROM
	forum_topics ft 
	inner join forum_posts fp on [b]fp.threadID[/b] = [b]ft.threadID[/b] 
	inner join members m1 on [b]ft.userid[/b] = [b]m1.id[/b] 
	inner join members m2 on [b]m2.id[/b] = [b]fp.userid[/b] 
        inner join forum_posts fp2 on [b]fp2.threadID[/b] = [b]ft.threadID[/b]
WHERE 
	[b]fp.userid[/b] = 1 
GROUP BY
	[b]ft.threadID[/b], 
	[b]ft.subject[/b], 
	[b]ft.userid[/b], 
	[b]m1.usr[/b], 
	[b]ft.room[/b], 
	[b]ft.last_post[/b], 
	ft.readers, 
	ft.answers, 
	ft.smiley, 
	[b]fp.id[/b], 
	[b]fp.userid[/b], 
	[b]fp.datum[/b], 
	[b]m2.usr[/b], 
	ft.poll, 
	ft.locked 
HAVING 
	[b]fp.datum[/b] = min([b]fp2.datum[/b])
ORDER BY
	[b]ft.room[/b] asc, [b]ft.last_post[/b] desc limit 0,20
Medlem sedan dec. 200012 464 inlägg
#4

jaha, då får du väl undersöka vad explain säger.

Medlem sedan feb. 20011 498 inlägg
#5

Resultatet från explain är bifogat.

larsg.gif
271 ms totalt · 4 externa anrop · v20260731065814-full.86ec41c2
125 ms — deklarationer (db)
0 ms — hämta statistik (cache)
143 ms — hämta tråd, inlägg och bilagor (db)
125 ms — ändringar (db)