Mysql
 sql >> Database >  >> RDS >> Mysql

MySQL Geo Search con prestazioni a distanza

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 .