Estoy creando una aplicación que se supone que consulta y devuelve cada Record
una en una tabla que está a X
kilómetros de distancia PointX
. Records
y PointX
las posiciones se determinan a partir de la (long/lat)
información proporcionada por Google Geocode API.
Soy nuevo en PostGIS. Después de una investigación rápida, encontré esta pregunta . La respuesta parece estar en la línea de:
SELECT *
FROM your_table
WHERE ST_Distance_Sphere(the_geom, ST_MakePoint(your_lon,your_lat)) <= radius_mi * 1609.34
El problema es: aunque solo estoy comenzando en SIG, cuando miro la consulta anterior, no puedo imaginar cómo esto puede usar un índice. Hay 2 llamadas a funciones. Me imagino que la mesa está siendo escaneada para cada uno Record
. Quiero estar equivocado :)
Pregunta: ¿PostGIS tiene algún tipo de índice capaz de hacer que la consulta anterior sea eficaz? Si no, ¿cuál sería el enfoque recomendado para hacer lo que necesito?
fuente
ST_SetSRID()
aST_MakePoint
antes de emitir a geografía en la consulta.Respuestas:
Hay dos claves para obtener un buen rendimiento de consultas geodésicas con tablas grandes con
geometry
columnas utilizando datos geográficos WGS 1984 (SRID 4326):ST_DWithin
función, que busca utilizando un índice espacial disponible, y encontrará características de geografía con una distancia cartesianaST_DWithin
puede usarloAsí que echemos un vistazo a lo que sucede en el mundo real. Primero necesitamos crear y llenar una tabla de un millón de puntos aleatorios:
Si ejecutamos la consulta ST_Distance, obtenemos el escaneo completo esperado de la tabla:
Ahora, si usamos
ST_DWithin
, todavía obtenemos un escaneo completo de la tabla (aunque más rápido):Y esta es la última pieza: construir el índice de cobertura (geografía de reparto):
Finalmente, el optimizador está usando el índice espacial, y se muestra, pero ¿cuáles son los tres órdenes de magnitud entre amigos?
Algunas advertencias:
Soy un nerd de la base de datos, por lo que la PC de mi casa tiene 16 Gb de RAM, seis núcleos de 3.3 Ghz y un SSD de 256 Gb para el espacio de tabla predeterminado de la base de datos; Su experiencia puede ser diferente
Volví a ejecutar el SQL de creación antes de cada consulta, para nivelar el campo de juego con respecto a las páginas "activas" en el caché, pero esto podría producir resultados ligeramente diferentes porque la misma semilla aleatoria no se usó para diferentes ejecuciones
Y una nota:
fuente