Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MYSQL Geo Search com desempenho à distância


A maneira mais rápida de fazer isso é usar as extensões geoespaciais para MySQL, o que deve ser bastante fácil, pois você já está usando uma tabela MyISAM. A documentação para essas extensões pode ser encontrada aqui:http:/ /dev.mysql.com/doc/refman/5.6/en/spatial-extensions.html

Adicione uma nova coluna com um tipo de dados POINT:
ALTER TABLE `adverts` 
ADD COLUMN `geopoint` POINT NOT NULL AFTER `longitude`
ADD SPATIAL KEY `geopoint` (`geopoint`)

Você pode então preencher esta coluna de seus campos de latitude e longitude existentes:
UPDATE `adverts` 
SET `geopoint` = GeomFromText(CONCAT('POINT(',`latitude`,' ',`longitude`,')'));

A próxima etapa é criar uma caixa delimitadora com base na latitude e longitude de entrada que serão usadas em seu WHERE cláusula como um CONTAINS limitação. Você precisará determinar um conjunto de X,Y POINT coordenadas que funcionam para seus requisitos com base na área de pesquisa desejada e no ponto de partida fornecido.

Sua consulta final pesquisará todos os POINT dados que estão dentro de sua pesquisa POLYGON , e você pode usar um cálculo de distância para refinar e classificar ainda mais seus dados:
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

Observe que o GeomFromText('Polygon((0 0,0 3,3 3,3 0,0 0))') acima não funcionará , você precisará substituir as coordenadas por pontos válidos em torno do início da pesquisa. Se você espera que a latitude/longitude mude, considere usar um gatilho para manter o POINT dados e SPATIAL KEY associada atualizado. Com grandes conjuntos de dados, você deve ver um desempenho muito melhor ao calcular uma distância para cada registro e filtrar usando um HAVING cláusula. Eu pessoalmente defini funções para uso na determinação da distância e na criação do POLYGON delimitador .