This sounds like a problem many others have posted about, but there’s a nuance to it that I can’t figure out: I don’t want to limit my bounds when asking for the nearest X data points, and the query needs to be fast.
Right now I’m using SQL as follows:
SELECT * FROM myTable WHERE col1 = 'String' AND col2 = 1
ORDER BY (latCol - <suppliedLat>) + (longCol - <suppliedLong>)
LIMIT X; //X is usually lower than 100
With Lat and Long stored as doubles, and the table containing about a million rows, this query takes ~6 seconds on our server – not fast enough. EXPLAIN SELECT shows me that it’s using no indexes (as expected – there’s only one index and it’s not location-related), performing a filesort, and hitting all ~1 million rows.
Removing the two WHERE clauses don’t improve performance at all, and the one index we applied to col1, col2 and a third col actually DECREASED the performance of this query, despite greatly increasing the speed of others.
My reading up on how to solve this leads me to believe that spatial indexing is the way to go, but we never intend to use any of the more advanced spatial features like polygons and circular bounds, we just need the speed. Is there an easy way to apply a spatial (or other sort of) index to an already-existing decimal-degrees table to improve the speed of the above query? Is there a better way of writing the query to make it more efficient?
The big killer is that most things i read about implementing a spatial index in MySQL seem to require changes in how you INSERT the data, but modifying our INSERT statements to use geo/spatial data types greatly increases our dev cycle.
The idea is to use a quadkey. It can look like this 12131212. Then each character in the key represents a leaf node (of a quadtree). If you want to find a similar location you can simply use the mysql substring in the where clause: WHERE SUBSTRING(
Field,0,4) = “1213”. For the above data it would return the first location 12131212 and any other location starting with 1213. Of course you can replace the character 1,2,3,4 with any other character more meaningful. You download my php class hilbert-curve @ phpclasses.org.