Det snabbaste sättet att göra detta är att använda de geospatiala tilläggen för MySQL, vilket borde vara tillräckligt enkelt eftersom du redan använder en MyISAM-tabell. Dokumentationen för dessa tillägg finns här:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
Lägg till en ny kolumn med en POINT-datatyp:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
Du kan sedan fylla i den här kolumnen från dina befintliga latitud- och longitudfält:
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
Nästa steg är att skapa en begränsningsruta baserad på indata latitud och longitud som kommer att användas i din WHERE
sats som en CONTAINS
begränsning. Du måste bestämma en uppsättning X,Y POINT
koordinater som fungerar för dina krav baserat på önskat sökområde och given utgångspunkt.
Din sista fråga kommer att söka efter alla POINT
data som finns i din sökning POLYGON
, och du kan sedan använda en avståndsberäkning för att ytterligare förfina och sortera dina data:
SELECT a.*,
ROUND( SQRT( ( ( (adverts.latitude - '53.410778') * (adverts.latitude - '53.410778') ) * 69.1 * 69.1 ) + ( (adverts.longitude - '-2.97784') * (adverts.longitude - '-2.97784') * 53 * 53 ) ), 1 ) AS distance
FROM adverts a
WHERE a.type_id = 3
AND CONTAINS(a.geopoint, GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))'))
HAVING distance < 25
ORDER BY distance DESC
LIMIT 0, 30
Observera att GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
i ovanstående fungerar inte , måste du ersätta koordinaterna med giltiga punkter runt din sökningsstart. Om du förväntar dig att lat/längden ska ändras bör du överväga att använda en trigger för att behålla POINT
data och tillhörande SPATIAL KEY
aktuellt. Med stora datamängder bör du se avsevärt förbättrad prestanda jämfört med att beräkna ett avstånd för varje post och filtrera med en HAVING
klausul. Jag definierade personligen funktioner för användning för att bestämma avståndet och skapa den gränsande POLYGON
.