Pas une réponse spécifique à MySql, mais cela améliorera les performances de votre instruction sql.
Ce que vous faites effectivement, c'est de calculer la distance à chaque point du tableau, pour voir si elle est à moins de 10 unités d'un point donné.
Ce que vous pouvez faire avant d'exécuter ce sql, c'est créer quatre points qui dessinent une boîte de 20 unités sur un côté, avec votre point au centre, c'est-à-dire. (x1, y1). . . (x4, y4), où (x1, y1) est (étant donné long + 10 unités, étant donné Lat + 10 unités). . . (givenLong - 10units, givenLat -10 units).
En fait, vous n'avez besoin que de deux points, en haut à gauche et en bas à droite, appelez-les (X1, Y1) et (X2, Y2)
Maintenant, votre instruction SQL utilise ces points pour exclure les lignes qui sont définitivement à plus de 10u de votre point donné, elle peut utiliser des index sur les latitudes et les longitudes, les ordres de grandeur seront donc plus rapides que ceux que vous avez actuellement.
par exemple
select . . .
where locations.lat between X1 and X2
and locations.Long between y1 and y2;
L'approche boîte peut renvoyer des faux positifs (vous pouvez ramasser des points dans les coins de la boîte qui sont> 10u à partir du point donné), vous devez donc toujours calculer la distance de chaque point. Cependant, cela sera encore plus rapide car vous avez considérablement limité le nombre de points à tester aux points dans la boîte.
J'appelle cette technique "Penser à l'intérieur de la boîte" :)
EDIT: Cela peut-il être mis dans une seule instruction SQL?
Je n'ai aucune idée de ce dont mySql ou Php est capable, désolé. Je ne sais pas où le meilleur endroit est de construire les quatre points, ni comment ils pourraient être passés à une requête mySql dans Php. Cependant, une fois que vous avez les quatre points, rien ne vous empêche de combiner votre propre instruction SQL avec la mienne.
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;
Je sais qu'avec MS SQL je peux construire une instruction SQL qui déclare quatre flottants (X1, Y1, X2, Y2) et les calcule avant l'instruction de sélection "principale", comme je l'ai dit, je ne sais pas si cela peut être fait avec MySql. Cependant, je serais toujours enclin à construire les quatre points en C # et à les transmettre en tant que paramètres à la requête SQL.
Désolé, je ne peux pas être plus d'aide, si quelqu'un peut répondre aux parties spécifiques de MySQL et Php, n'hésitez pas à modifier cette réponse pour le faire.