Tja, den enda fråga som kan fungera hittills är Simons... men det är verkligen överdrivet - en så komplex otäck fråga (2 underfrågor med 2 fackföreningar!) för en så enkel sak att du behöver lägga ut en belöning? :-) Och om du har typ 1000+ användare kommer frågan att vara långsam som fan - kom ihåg att den är kvadratisk och på grund av fackföreningar i underfrågor, skulle knappt något index användas!
Jag skulle föreslå att du tänker om designen igen och tillåter två dubbletter av rader för en vänskap:
id Person1 Person2 status
1 1 2 friend
2 2 1 friend
3 1 3 friend
4 3 1 friend
Du kanske tycker att det är ineffektivt men efter förenkling kommer du att kunna skriva om frågan till enkla kopplingar:
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'
vilket kommer gå fort som fan! (Glöm inte att lägga till index för Person1,2.) Jag har rekommenderat en liknande förenkling (omskrivning subqueries to joins) i annan mycket otäck datastruktur och det har påskyndat frågan från evighet till blixtmoment!
Så vad som kan ha sett ut som en stor overhead (2 rader för en vänskap) är faktiskt en stor optimering :-)
Dessutom kommer det att göra frågor som "hitta alla vänner till X" mycket enklare. Och inga fler belöningar kommer att behöva spenderas :-)