sql >> Base de Datos >  >> RDS >> Mysql

MYSQL Geo Search con rendimiento a distancia

La forma más rápida de hacer esto es usar las extensiones geoespaciales para MySQL, lo que debería ser bastante fácil ya que ya está usando una tabla MyISAM. La documentación de estas extensiones se puede encontrar aquí:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html

Agregue una nueva columna con un tipo de datos PUNTO:

ALTER TABLE `adverts` 
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)

Luego puede completar esta columna a partir de sus campos de latitud y longitud existentes:

UPDATE `adverts` 
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));

El siguiente paso es crear un cuadro delimitador basado en la latitud y longitud de entrada que se utilizará en su WHERE cláusula como CONTAINS restricción. Deberá determinar un conjunto de X,Y POINT coordenadas que funcionan para sus requisitos en función del área de búsqueda deseada y el punto de partida dado.

Su consulta final buscará todos los POINT datos que están dentro de su búsqueda POLYGON , y luego puede usar un cálculo de distancia para refinar y ordenar aún más sus datos:

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

Tenga en cuenta que GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))') en lo anterior no funcionará , deberá reemplazar las coordenadas con puntos válidos alrededor de su inicio de búsqueda. Si espera que cambie la latitud/longitud, debería considerar usar un disparador para mantener el POINT datos y SPATIAL KEY asociada A hoy. Con grandes conjuntos de datos, debería ver un rendimiento mucho mejor que calcular una distancia para cada registro y filtrar usando un HAVING cláusula. Personalmente definí funciones para usar en la determinación de la distancia y la creación del límite POLYGON .