I can't speak on the subject of performance in MySQL but when working on the same problem in SQL Server I build a box based on my distance
than I can limit results quickly in WHERE
clause by simply verifying for Lat
and Long
to be within boundaries. At that point it becomes simple arithmetic comparison. After I have narrowed down number of results at that time I check the Distance
from my original point.
The whole point of building a box first is to reduce number of records that are involved in complex mathematical calculation.
Here is my example from SQL Server.
DECLARE @Lat DECIMAL(20, 13) = 35.7862
,@Long DECIMAL(20, 13) = -80.3095
,@Radius DECIMAL(7, 2) = 5
,@Distance DECIMAL(10, 2)
,@Earth_Radius INT = 6371000;
SET @Distance = @Radius * 1609.344;
DECLARE @NorthLat DECIMAL(20, 13) = @Lat + DEGREES(@distance / @Earth_Radius)
,@SouthLat DECIMAL(20, 13) = @Lat - DEGREES(@distance / @Earth_Radius)
,@EastLong DECIMAL(20, 13) = @Long + DEGREES(@distance / @Earth_Radius / COS(RADIANS(@Lat)))
,@WestLong DECIMAL(20, 13) = @Long - DEGREES(@distance / @Earth_Radius / COS(RADIANS(@Lat)));
SELECT *
FROM CustomerPosition AS cp
WHERE (
cp.Lat >= @SouthLat
AND cp.Lat <= @NorthLat )
AND (
cp.Long >= @WestLong
AND cp.Long <= @EastLong )
Results of original select I store it into temp table and than evaluate it to see which ones actually Within
specified distance.