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

Pesquisando os 5 locais mais próximos de um CEP - que caminho devo seguir?


Primeiro alguns comentários...

Eu vi dezenas (não milhões) de implementação aqui e em outros fóruns; a sua é melhor que a maioria.

De acordo com uma fonte de dados (que por acaso baixei), existem cerca de 3,2 milhões de cidades no mundo.

Para desempenho, você precisa evitar verificar todas as 3 milhões de linhas. Você começou bem com a caixa delimitadora em crescimento. Observe que você deve ter
INDEX(lat, lon),
INDEX(lon, lat)

O Otimizador escolherá entre eles e a primeira consulta (com o COUNT(*) ) verá isso como 'cobrindo'. Será uma faixa ao redor do globo ou uma cunha; uma melhoria definitiva sobre 3M linhas. A pior latitude (+34 graus) tem 96 mil cidades. (1 grau =69 milhas / 111 km.) Para um décimo de grau, 34,4 é o pior, com 10 mil cidades.

(Sim, eu gosto desse tipo de quebra-cabeça de dados.)

E, vejo que você lida com a linha de data e os pólos. Eu não acho que você pode melhorar em tê-los como um caso especial.

(Só dei uma olhada nas fórmulas e constantes.)

Ajuda de indexação Geohash e Z-order. Mas eles têm um problema em que você precisa checar até 4 áreas ao redor do alvo -- É como não perceber que os inteiros 199999 e 200000 estão muito próximos um do outro, apesar do primeiro dígito de cada um ser diferente.

"O usuário passa o código postal ou o nome da cidade" - essa é uma consulta pontual em uma das duas tabelas simples. (Exceto que pode haver dups - mais de 320 cada de "san jose" e "san antonio". Bem abaixo na lista está o primeiro nome não espanhol:"victoria", com apenas 144 cidades.)

Segundo, minha implementação... (Tem algumas semelhanças com o seu.)

http://mysql.rjweb.org/doc.php/latlng

Isso melhora o desempenho usando PARTITIONing para manter a caixa delimitadora em aproximadamente um quadrado, em vez de uma faixa ou cunha. Se você estiver procurando os 5 mais próximos, meu algoritmo raramente tocará mais do que algumas dúzias de linhas, e essas linhas serão 'agrupadas' em um pequeno número de blocos, mantendo assim o número de acertos de disco muito baixo.

Uma coisa crítica no meu design é ter todas as colunas necessárias em uma tabela. Depois de encontrar os 5 mais próximos, você pode ir para outras mesas para pegar coisas auxiliares (número de telefone, etc).

Quanto aos CEPs, transforme-os em lat/lon antes de iniciar a busca pelos 5 mais próximos.

É muito provável que uma junção dentro do algoritmo destrua o desempenho.