2009-02-09 9 views
6

Tengo una lista de registros en mi base de datos y cada registro está asociado con un código postal.¿Cuál es la mejor manera de consultar una base de datos para registros dentro de n millas de un código postal?

¿Cuál es la "mejor práctica" para consultar todos los registros en mi base de datos para encontrar todas las entradas que están dentro de n millas de otro código postal?

Cada código postal tiene una latitud/longitud asociada a él en la base de datos, así que sé que tendré que usar eso. Sin embargo, no puedo imaginarme ejecutar ningún tipo de fórmula de distancia en cada par de códigos postales, convirtiendo a millas y rechazando aquellas que no están dentro de mi radio.

Parece tremendamente costoso desde el punto de vista informático para una consulta tan común.

También he considerado hacer un cálculo previo de todos los pares, pero parece demasiado grande como para considerarlo también. Hay aproximadamente ~ 40,000 códigos postales en los EE. UU. Entonces, una base de datos de todos los pares de cada código postal sería (40,000)^2, o 1,6 billones de entradas.

Sé que este es un problema común en los sitios web, así que con suerte alguien me puede orientar en la dirección correcta de la mejor manera. Estoy usando SQL Server 2008 y si hay soluciones prefabricadas, entonces genial, porque realmente no quiero volver a inventar la rueda en esta instancia.


pregunta relacionada: Getting all zip codes within radius (esto no me ayuda)
Además, sé de este proyecto SourceForge pero es abandonado y ya no está en uso.

Respuesta

7

Me ejecutar una consulta que devuelve todos los registros entre corchetes en el sobre cuadrado encompasing el círculo de búsqueda radial (minlat < lat < maxlat y minlong < largo < maxlong), y luego después del proceso de este para devolver sólo los puntos dentro de la círculo de radio en sí. (asegúrese de que sus campos largos y lat están indexados).

Si quieres ser elegante, el servidor SQL admite spatial indexes.

+0

dang: ¡pásame! –

0

Esto es, de hecho, un problema muy difícil de resolver. Te recomendaría que hagas trampa haciendo una base de datos previa. Cree una cuadrícula de cualquier tipo de cercanía que necesite encontrar, por ejemplo, tome cada 10 millas en cada dirección, agregue una entrada a la base de datos para cada zip para ese punto de la grilla y la distancia, y luego, cuando entre una consulta, usted primero traduzca el punto de consulta a uno de sus puntos de cuadrícula. Ahora puedes buscar la distancia con bastante facilidad.

Esta solución significa básicamente espacio comercial por tiempo, por lo que puede obtener una base de datos bastante grande rápidamente. La buena noticia es que es muy fácil de indexar.

+0

Una precomputación de todos los pares sería algo grande. Aprox. 40,000 códigos postales us, por lo que (40,000)^2 para cada rango sería una gran cantidad de entradas de la base de datos. – mmcdole

+0

Eso sería aproximadamente ~ 1,6 billones de entradas para cada rango ... No sé si eso sería una opción. – mmcdole

+0

En realidad, lo que Ola Bini sugiere es que puede acortar la cantidad de entradas en gran medida si puede limitar la distancia máxima entre los códigos postales (10 millas en su ejemplo) – tehvan

3

corro a site that needs to run this query about once per second per user, y esto es lo que he aprendido:

En primer lugar, asegúrese de que su ubicación de la tabla tiene índices en Lat y Lon. Esa es la diferencia entre los tiempos de respuesta de 20 ms y 15 s si tiene millones de registros.

Comience con una consulta de recuadro delimitador para obtener un conjunto de ubicaciones para trabajar. Luego calcule las distancias en esas, ordene, y si es exigente con la precisión, filtre algunas.

Francamente, no me preocuparía precomputar nada.Como digo, ejecuto este tipo de consulta en una tabla de ubicación con 6,000,000 entradas, y generalmente devuelve resultados en < 50ms. Dependiendo de tus necesidades, eso realmente debe ser lo suficientemente rápido.

¡Buena suerte!

+0

Gracias por su información personal sobre este tema. Lo aprecio. – mmcdole

0

Debería mirar GeoNames.org. Puede consultar su webservice para lo que está buscando, o puede dl su base de datos.

Cuestiones relacionadas