Digamos que quiero encontrar 20 negocios más cercanos cerca de mí.
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
Hay 1.6 millones de negocios. Por supuesto, es estúpido calcular la distancia para todos ellos y luego ordenarlos.
Ahí es donde entra en juego el índice geoespacial, ¿verdad?
Entonces, ¿qué comando SQL necesito para lanzar?
Nota:
- Estoy usando el índice espacial mysql myisam . Sin embargo, no especifiqué esto antes. Así que aceptaré a quienes lo respondan para mostrar mi agradecimiento y hacer otra pregunta.
- No quiero calcular la distancia para toda la tabla
- No quiero calcular la distancia para ninguna región que todavía sea ineficiente
- Quiero calcular la distancia para un número razonable de puntos porque quiero ordenar los puntos por distancia y poder mostrar los puntos 1-20, 21-40, 41-60, etc.
spatial-database
optimization
mysql-spatial
user4951
fuente
fuente
Respuestas:
Las consultas espaciales son definitivamente lo que hay que usar.
Con PostGIS, primero probaría algo simplista como este y ajustaría el rango según sea necesario:
Esto compararía puntos (en realidad sus cuadros delimitadores) utilizando el índice espacial, por lo que debería ser rápido. Otro enfoque que viene a la mente es almacenar su ubicación en el búfer y luego intersecar ese búfer con los datos originales, lo que puede ser aún más eficiente.
fuente
Si todo lo que está buscando son búsquedas de puntos de proximidad (consultas de vecinos más cercanos), entonces no desea usar los viejos ST_DWithin o ST_Distance + ORDER BY para eso.
Ya no.
Ahora que se envió PostGIS 2.0, debería usar el soporte de índice knngist (una característica nativa de PostgreSQL). Serán órdenes de magnitud más rápido.
Un extracto de esta entrada de blog que describe cómo usar knn gist sin PostGIS :
Lo suficientemente interesante, el recorrido del índice devolverá las características en orden de proximidad, por lo que no es necesario hacer una clasificación (es decir, ordenar por) para obtener los resultados.
Sin embargo, si desea usarlo junto con PostGIS, ahora es realmente fácil. Solo sigue estas instrucciones .
La parte relevante es esta:
Pero no confíes en mi palabra. Míralo tú mismo :)
fuente
Con PostGIS 2.0 en PostgreSQL 9.1, puede usar el operador vecino más cercano indexado KNN , por ejemplo:
Lo anterior debería consultar en unos pocos milisegundos.
Durante los siguientes múltiplos de 20, a modificar
OFFSET 20
,OFFSET 40
etc ...fuente
<->
? Gracias.<->
es un operador que devuelve la distancia 2D.MySQL espacial
Todos aquí te están diciendo cómo hacerlo con PostgreSQL usando KNN, sin decirte las ventajas. Usando MySQL no puede determinar el vecino más cercano sin calcular la distancia para todos los vecinos. Eso es extremadamente lento. Con PostgreSQL esto se puede hacer en un índice. Ni MySQL ni MariaDB admiten actualmente KNN
fuente