Il modo più veloce per farlo è utilizzare le estensioni geospaziali per MySQL, il che dovrebbe essere abbastanza semplice poiché stai già utilizzando una tabella MyISAM. La documentazione per queste estensioni può essere trovata qui:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html
Aggiungi una nuova colonna con un tipo di dati POINT:
ALTER TABLE `adverts`
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)
Puoi quindi compilare questa colonna dai campi di latitudine e longitudine esistenti:
UPDATE `adverts`
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));
Il passaggio successivo consiste nel creare un riquadro di delimitazione basato sulla latitudine e la longitudine di input che verranno utilizzate nel tuo WHERE
clausola come CONTAINS
vincolo. Dovrai determinare un insieme di X,Y POINT
coordinate che funzionano per le tue esigenze in base all'area di ricerca desiderata e al punto di partenza specificato.
La tua query finale cercherà tutti i POINT
dati che si trovano all'interno della tua ricerca POLYGON
e puoi quindi utilizzare un calcolo della distanza per perfezionare e ordinare ulteriormente i tuoi dati:
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
Nota che il GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))')
in quanto sopra non funzionerà , dovrai sostituire le coordinate con punti validi intorno all'inizio della tua ricerca. Se prevedi che la lat/long cambi, dovresti prendere in considerazione l'utilizzo di un trigger per mantenere il POINT
dati e SPATIAL KEY
associata aggiornato. Con set di dati di grandi dimensioni dovresti vedere prestazioni notevolmente migliorate rispetto al calcolo di una distanza per ogni record e al filtraggio utilizzando un HAVING
clausola. Ho definito personalmente le funzioni da utilizzare per determinare la distanza e creare il POLYGON
di delimitazione .