Welnu, de enige vraag die tot nu toe zou kunnen werken, is die van Simon... maar dat is echt overkill - zo'n complexe vervelende vraag (2 subquery's met 2 vakbonden!) voor zo eenvoudig ding dat je een premie moet plaatsen? :-) En als je meer dan 1000 gebruikers hebt, zal de zoekopdracht ontzettend traag zijn - onthoud, het is kwadratisch, en vanwege unies in subquery's, zou er nauwelijks een index worden gebruikt!
Ik stel voor om het ontwerp opnieuw te bekijken en 2 dubbele rijen toe te staan voor een vriendschap:
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Je zou kunnen denken dat dit inefficiënt is, maar door de volgende vereenvoudiging kan de query worden herschreven naar eenvoudige joins:
select f1.Person2 as common_friend
from friends as f1 join friends as f2
using (Person2)
where f1.Person1 = '$id1' and f2.Person1 = '$id2'
and f1.status = 'friend' and f2.status = 'friend'
die zal snel zijn als de hel! (Vergeet niet om indices voor Person1,2 toe te voegen.) Ik heb een soortgelijke vereenvoudiging geadviseerd (herschrijven subqueries naar joins) in een andere zeer vervelende gegevensstructuur en het heeft de zoekopdracht versneld van eeuwigheid tot bliksemsnel!
Dus wat eruitzag als een grote overhead (2 rijen voor één vriendschap) is eigenlijk een grote optimalisatie :-)
Ook worden zoekopdrachten als "vind alle vrienden van X" veel gemakkelijker. En er hoeven geen premies meer te worden uitgegeven :-)