Non è una risposta specifica per MySql, ma migliorerà le prestazioni della tua dichiarazione sql.
Quello che stai effettivamente facendo è calcolare la distanza da ogni punto della tabella, per vedere se è entro 10 unità di un dato punto.
Quello che puoi fare prima di eseguire questo sql è creare quattro punti che disegnano una scatola di 20 unità su un lato, con il tuo punto al centro. (x1, y1). . . (x4, y4), dove (x1, y1) è (dato lungo + 10 unità, dato Lat + 10 unità). . . (datoLungo - 10 unità, datoLat -10 unità).
In realtà, hai solo bisogno di due punti, in alto a sinistra e in basso a destra chiamali (X1, Y1) e (X2, Y2)
Ora la tua istruzione SQL usa questi punti per escludere righe che sono sicuramente più di 10u dal tuo punto dato, può usare gli indici su latitudini e longitudini, quindi gli ordini di grandezza saranno più veloci di quello che hai attualmente.
per esempio
select . . .
where locations.lat between X1 and X2
and locations.Long between y1 and y2;
L'approccio box può restituire falsi positivi (è possibile raccogliere punti negli angoli del box che sono> 10u da un determinato punto), quindi è comunque necessario calcolare la distanza di ciascun punto. Tuttavia, questo sarà di nuovo molto più veloce perché hai drasticamente limitato il numero di punti da testare ai punti all'interno del riquadro.
Chiamo questa tecnica "Pensare dentro la scatola" :)
EDIT: questo può essere inserito in un'istruzione SQL?
Non ho idea di cosa sia capace mySql o Php, scusa. Non so dove sia il posto migliore per costruire i quattro punti o come possano essere passati a una query mySql in Php. Tuttavia, una volta che hai i quattro punti, non c'è niente che ti impedisce di combinare la tua istruzione SQL con la mia.
select name,
( 3959 * acos( cos( radians(42.290763) )
* cos( radians( locations.lat ) )
* cos( radians( locations.lng ) - radians(-71.35368) )
+ sin( radians(42.290763) )
* sin( radians( locations.lat ) ) ) ) AS distance
from locations
where active = 1
and locations.lat between X1 and X2
and locations.Long between y1 and y2
having distance < 10 ORDER BY distance;
So che con MS SQL posso creare un'istruzione SQL che dichiara quattro float (X1, Y1, X2, Y2) e li calcola prima dell'istruzione select "principale", come ho detto, non ho idea se questo può essere fatto con MySql. Tuttavia, sarei ancora propenso a costruire i quattro punti in C # e passarli come parametri alla query SQL.
Mi dispiace non poter essere più di aiuto, se qualcuno può rispondere a specifiche porzioni di MySQL e Php di questo, sentiti libero di modificare questa risposta per farlo.