Vad WTF står för vet jag inte, men... din ursprungliga fråga är inte helt optimal.
FROM
tblmyfriends AS t1,
tblmember AS t2,
tblonline AS t3
WHERE t1.memberID = $ID AND t2.suspended = 0
Det här skapar en kryssprodukt mellan t1, t2 och t3. I princip kommer varje rad i t1 att kombineras med alla rader i t2, och var och en av resultatets rader kombineras med samtliga rader i t3. Om du har 10 rader i var och en av tabellerna, innehåller kryssprodukten från början 1000 rader... (och gissningsvis är dina tabeller större än 10 rader...)
När du har gjort det ser villkoret i where till att du "bara" behåller de rader där
t1.memberID har ett visst värde (vilket i mitt räkneexempel gäller 100 rader, om memberID är unikt i t1, och x*100 om det står x ggr). På samma sätt tar t2.suspended = 0 bort alla rader där detta inte är uppfyllt vilket väl troligen inte tar bort så värst många rader.
Men obs! att villkoret t1.memberID = $ID är uppfyllt för bra många rader där t1.friendID != memberID i antingen t2, t3 eller båda.
Du har alltså skapat en JÄTTEtabell, där andelen intressanta rader är en pytteliten minoritet.
För att (ur optimeringssynpunkt) göra saken värre använder du inte ens denna gigantiska tabell för att göra jämförelserna i direkt. Istället gör du för varje rad i din JÄTTEtabell en sökning av alla rader i en av de ursprungliga tabellerna efter en värdematchning, och detta görs en gång per kolumn du vill ta ut.
"SELECT DISTINCT
(SELECT username FROM tblmember -- dvs samma som t2
WHERE memberID = t1.friendID) AS friendusername,
(SELECT memberID FROM tblmember -- dvs samma som t2
WHERE memberID = t1.friendID) AS memberID,
(SELECT DATE_FORMAT(last_visit, '%Y-%m-%d %H:%i') FROM tblmember -- dvs samma som t2
WHERE memberID = t1.friendID) AS datetime,
(SELECT memberID FROM tblonline -- dvs samma som t3
WHERE memberID = t1.friendID) AS online,
(SELECT activity FROM tblonline -- dvs samma som t3
WHERE memberID = t1.friendID) AS activity
Så för varje rad i din jättetabell söker vi igenom t2 3 gånger, och t3 2 gånger. Låt oss säga att vi kom ner i att din jättetabell blev 90 rader stor. Då letar vi alltså igenom 90*(3*10)+ 90*(2*10) = 270+180=450 rader istället för 10.... som var det ursprungliga antalet rader i t1, t2 och t3. :o
(Nu har du visserligen troligen en optimerare någonstans som förbättrar frågan genom att formulera om den lite här och var innan den skickas för evaluering... men det finns gränser för vad den kan räta ut.)
Om vi jämför detta med Eriks kod....
- Vi joinar kontrollerat tabellerna så att det enda som slås ihop är de rader vi faktiskt var intresserade av:
from
tblmyfriends f
inner join tblmember m
on m.memberID = f.friendID
left outer join tblonline m
on o.memberID = f.friendID
På vilken godtycklig rad som helst här kommer m.memberID att vara samma som o.memberID och f.friendID. WHERE-delen begränsar dessutom resultatet till att gälla de rader i alla tre tabellerna som hör ihop med bara ETT visst f.memberID och för icke-suspendade medlemmar.
select
m.username as friendusername,
m.memberID,
date_format(m.last_visit, '%Y-%m-%d %H:%i') as datetime,
o.memberId as online,
o.activity
Här plockas dessutom kolumnvärdena ut från den resulterande sammanslagna tabellen, så vi behöver bara gå igenom den en gång.