How to optimize SQL query geolocating data?

Alex

Our task is to find the properties within the location specified by a client. We have a MySQL table that contains the longitudes and latitudes of properties.

address longitude latitude

address 1 42.4001742 -71.1213472

address 2 42.4651592 -71.01366

So, logically, we can do a SQL search based on the client location

Select * from addresses where longitude between (client.location. longitude + 0.1) 
and (client.location. longitude - 0.1) and latitude between 
(client.location. latitude + 0.1) and (client.location. latitude - 0.1)

How effective is this search in case of many thousands properties? What is a possible way to optimize this search?

O. Jones

You will want this index (use a BTREE index).

CREATE INDEX latlon ON addresses (latitude, longitude);

Your query will do an index range scan on the latitude (the south-north direction) and then filter on the east-west direction. That is fairly efficient.

One degree of latitude (south-north) is 69 miles or 111.111 km (based on the Napoleonic definition of meter ... ten million of them from the equator to the pole).

The distance per degree of longitude (west-east) varies based on how far you are from the equator. The further you are from the equator the shorter the distance. In Somerville, Mass, USA, one longitude degree is about 51 miles. (You did tell us where you are by your example.)

So if you want a bounding box three miles in each direction centered around (42.4002 -71.1213) you need this filtering clause.

WHERE latitude  BETWEEN  42.4002 - (3.0/69.0) 
                    AND  42.4002 + (3.0/69.0)
  AND longitude BETWEEN -71.1213 - (3.0/(69.0 * COS(RADIANS(42.4002))))
                    AND -71.1213 + (3.0/(69.0 * COS(RADIANS(42.4002))))

If you want to give your box in km, use 111.111 in place of 69.0. If you want a differently sized box use a different number in place of 3.0.

That filter expression uses the index I mentioned just fine.

If all the locations in your table are spread out mostly in the east-west direction but not the north-south direction (for example, along the Massachusetts Turnpike) then switch the order of the two columns in the index to get better selectivity. But usually this doesn't matter.

CREATE INDEX lonlat ON addresses (longitude, latitude);

You may find it helpful to read this.

Pro tip it's best to give lat/lon examples in oceans or cornfields.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related