Digamos que eu queira encontrar as 20 empresas mais próximas perto de mim.
My table structure is like this:
BusinessID varchar(250) utf8_unicode_ci No None Browse distinct values Change Drop Primary Unique Index Fulltext
Prominent double No None Browse distinct values Change Drop Primary Unique Index Fulltext
LatLong point No None Browse distinct values Change Drop Primary Unique Index Fulltext
FullTextSearch varchar(600) utf8_bin No None Browse distinct values Change Drop Primary Unique Index Fulltext
With selected: Check All / Uncheck All With selected:
Print viewPrint view Propose table structurePropose table structureDocumentation
Add new fieldAdd field(s) At End of Table At Beginning of Table After
Indexes: Documentation
Action Keyname Type Unique Packed Field Cardinality Collation Null Comment
Edit Drop PRIMARY BTREE Yes No BusinessID 1611454 A
Edit Drop Prominent BTREE No No Prominent 0 A
Edit Drop LatLong BTREE No No LatLong (25) 0 A
Edit Drop sx_mytable_coords SPATIAL No No LatLong (32) 0 A
Edit Drop FullTextSearch FULLTEXT No No FullTextSearch 0
Existem 1,6 milhão de negócios. É claro que é estúpido calcular a distância para todos eles e depois classificá-lo.
É aí que o índice geoespacial entra em ação, certo?
Então, qual SQL Comman eu preciso lançar?
Nota:
- Eu estou usando o índice espacial mysql myisam . No entanto, eu não especifiquei isso antes. Por isso, aceitarei aqueles que responderem para mostrar minha gratidão e fazer outra pergunta.
- Eu não quero calcular a distância para toda a tabela
- Não quero calcular a distância para nenhuma região que ainda seja ineficiente
- Eu quero calcular a distância para um número razoável de pontos, porque quero classificar os pontos por distância e poder exibir os pontos 1-20, 21-40, 41-60 etc.
spatial-database
optimization
mysql-spatial
user4951
fonte
fonte
Respostas:
As consultas espaciais são definitivamente a melhor opção.
Com o PostGIS, primeiro tentaria algo simplista como esse e ajustaria o alcance conforme necessário:
Isso compararia pontos (na verdade, suas caixas delimitadoras) usando o índice espacial, portanto deve ser rápido. Outra abordagem que vem à mente é armazenar em buffer a sua localização e, em seguida, cruzar esse buffer com os dados originais, o que pode ser ainda mais eficiente.
fonte
Se tudo o que você procura são pesquisas de pontos de proximidade (consultas de vizinhos mais próximos), não será necessário usar os STs antigos ST_DWithin ou ST_Distance + ORDER BY para isso.
Não mais.
Agora que o PostGIS 2.0 foi lançado, você deve usar o suporte ao índice knngist (um recurso nativo do PostgreSQL). Serão ordens de magnitude mais rápidas.
Um trecho desta entrada do blog que descreve como usar o knn gist sem o PostGIS :
Interessante o suficiente, a travessia do índice retornará os recursos em ordem de proximidade, portanto, não é necessário fazer uma classificação (ou seja, ordenar por) para os resultados!
No entanto, se você quiser usá-lo juntamente com o PostGIS, agora é realmente fácil. Basta seguir estas instruções .
A parte relevante é esta:
Mas não aceite minha palavra. Time it yourself :)
fonte
Com o PostGIS 2.0 no PostgreSQL 9.1, você pode usar o operador vizinho mais próximo indexado pelo KNN , por exemplo:
O acima deve consultar dentro de alguns milissegundos.
Para os próximos múltiplos de 20, modificar a
OFFSET 20
,OFFSET 40
, etc ...fonte
<->
? Obrigado.<->
é um operador que retorna a distância 2D.MySQL Spatial
Todo mundo aqui está lhe dizendo como fazer isso com o PostgreSQL usando o KNN, sem lhe dizer as vantagens. Usando o MySQL, você não pode determinar o vizinho mais próximo sem calcular a distância para todos os vizinhos. Isso é extremamente lento. Com o PostgreSQL, isso pode ser feito em um índice. Nem o MySQL nem o MariaDB atualmente suportam o KNN
fonte