No es una respuesta específica de MySql, pero mejorará el rendimiento de su declaración sql.
Lo que efectivamente está haciendo es calcular la distancia a cada punto de la tabla, para ver si está dentro de las 10 unidades de un punto dado.
Lo que puede hacer antes de ejecutar este sql es crear cuatro puntos que dibujen un cuadro de 20 unidades a un lado, con su punto en el centro, es decir. (x1, y1). . . (x4, y4), donde (x1, y1) es (dado largo + 10 unidades, dado Lat + 10 unidades). . . (givenLong - 10units, givenLat -10 unidades).
En realidad, solo necesitas dos puntos, arriba a la izquierda y abajo a la derecha, llámalos (X1, Y1) y (X2, Y2)
Ahora su declaración SQL usa estos puntos para excluir filas que definitivamente están a más de 10u de su punto dado, puede usar índices en las latitudes y longitudes, por lo que serán órdenes de magnitud más rápidos que los que tiene actualmente.
p.ej
select . . .
where locations.lat between X1 and X2
and locations.Long between y1 and y2;
El enfoque de cuadro puede devolver falsos positivos (puede recoger puntos en las esquinas del cuadro que están> 10u desde el punto dado), por lo que aún necesita calcular la distancia de cada punto. Sin embargo, esto nuevamente será mucho más rápido porque ha limitado drásticamente el número de puntos para probar a los puntos dentro del cuadro.
Yo llamo a esta técnica "Pensar dentro de la caja" :)
EDITAR: ¿Se puede poner esto en una declaración SQL?
No tengo idea de lo que mySql o Php es capaz, lo siento. No sé dónde es el mejor lugar para construir los cuatro puntos, o cómo podrían pasarse a una consulta mySql en Php. Sin embargo, una vez que tenga los cuatro puntos, no hay nada que le impida combinar su propia declaración SQL con la mía.
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;
Sé que con MS SQL puedo construir una declaración SQL que declara cuatro flotantes (X1, Y1, X2, Y2) y los calcula antes de la declaración de selección "principal", como dije, no tengo idea si esto se puede hacer con MySql. Sin embargo, todavía estaría inclinado a construir los cuatro puntos en C # y pasarlos como parámetros a la consulta SQL.
Lo siento, no puedo ser más ayuda, si alguien puede responder las partes específicas de MySQL y Php de esto, no dude en editar esta respuesta para hacerlo.