Pregunta

Tengo un sitio que estoy construyendo, es una aplicación que crea combinaciones de correspondencia (más o menos ...) basado en un par de las preferencias del usuario. Puede generar cartesiana se une a la pena de los datos sin ningún problema pero se mete en las necesidades de la empresa para hacer la vida un poco más difícil ...

Tengo que generar la aplicación de manera que, después de comprobar los códigos postales de los empleados remotos, crea mensajes de correo electrónico a los objetivos de los medios de comunicación sobre la base de qué tan lejos de ese empleado es el objetivo de los medios de comunicación. Digamos, por ejemplo, los empleados son voluntarios en los que trabajan bien conocidos. La empresa quiere enviar por correo electrónico los medios de comunicación dentro de un radio de 5 millas de estos empleados un mensaje sobre el trabajo que el empleado está haciendo. Aquí es donde las cosas se complican ... Tengo varias opciones aquí, que voy a describir los intentos y los fracasos:

  1. El radio más grande es de 20 millas. Puedo crear una tabla de base de datos que contiene los registros de cada código postal en los EE.UU., se unieron a cada código postal dentro de 20 millas de ese código postal. El conjunto de datos se ve algo como (los nombres son diferentes esto es por el bien del argumento):
    [SourceZip] | [City] | [Estado] | [CloseZip] | [City] | [Estado] | [Distancia] Falla: A modo de ejemplo, Nueva York tiene 350k registros del conjunto de datos anterior (y otros estados son peores!). tiempo de carga promedio en esa página? 6 minutos ... no está ocurriendo. Verifiqué esto estableciendo los puntos de interrupción, es durante la etapa de DataAdapter.Fill () que se produce la desconexión.

  2. (Éste nunca se implementó debido a un problema de logística) hago una conexión de base para cada zip empleado para cremalleras de destino de medios con una distancia de x o menos. Excepto que los archivos de origen y los objetivos de los medios combinados pueden llegar a más de 34K correos electrónicos individualizados. 34k conexiones de base de datos? aunque pudiera idear una manera de reutilizar las búsquedas de código postal, hice algunas comprobaciones de prueba en la base de datos y se encontró que hay 500 códigos postales distintos en Nueva York, donde los empleados trabajaban. 500 db conexiones? Dudo que iba a funcionar pero podría estar sorprendido.

  3. Mi último esquema para evitar el problema está en que la esperanza de que el servidor Web se ejecuta un mejor juego, entonces el objeto .NET conjunto de datos al obtener un nuevo conjunto de datos se parece a:
    [postal] | [Longitud] | [Latitud]
    A continuación, haciendo una fórmula de distancia de averiguar si los datos funciona. Esto se basa en gran medida en los procesadores en el servidor web. ¿Es esta una apuesta que vale la pena, o voy a encontrar el mismo daño de tiempo de carga en este intento, así?

    ¿Hay una mejor manera?

    Agradezco cualquier entrada, incluso si se confirma mis temores de que este proyecto simplemente no podría funcionar .

Notas adicionales : Yo no tengo el control del servidor, y yo estoy corriendo SQL2K :( estoy programando el sitio en Visual Studio 2005, Framework 2.0 podría obtener actualizado a.. SQL2005 y VS2008 en los próximos meses aunque.

¿Fue útil?

Solución

Si usted tiene un conjunto de datos para sus empleados, y un conjunto de datos para sus medios de comunicación, y un tercer conjunto de datos para la distancia betweeen origen y de destino cremalleras, es posible ahorrar un poco de tiempo de unirse a las 3 mesas ...

SELECT *
FROM Employees_List
   INNER JOIN 
       (Media_List INNER JOIN Distance_List ON Media_List.Zip = Distance_List.Target_Zip)
   ON Employees_List.Zip = Distance_List.Source_Zip
WHERE distance_Miles <=5

De esta manera se establece la relación entre el empleado y de medios con la distancia.

Otros consejos

Si usted tiene una base de datos de código postal con coordenadas de longitud / latitud, se podría calcular la distancia sobre la marcha con mi función Haversine (Véase mi respuesta a esta pregunta ).

Esto funciona muy bien en aplicaciones web con la totalidad de los datos de código postal de Estados Unidos.

La consulta se vería como algo similar a esto:

select * from zip where 
   dbo.udf_Haversine(zip.lat,zip.long, @lat, @lon) < 20   -- (miles)

Usted no aplicar esto a la dirección de cada destinatario, pero sería determinar los códigos postales dentro de su radio de primera (en una consulta anidada, o con un CTE), y luego unirse a todas las direcciones que usted necesita para enviar un correo a.

Editar Después de la investigación de la respuesta con la función Haversine es la ruta que tomaría ... no es tan intenso como la función de los usos db (que serán fijadas:))

Debe no calcular las distancias cada vez, es una pesada cálculo a partir de lat / long a Lat / Long, y si lo está haciendo más de una vez, es innecesaria.

Una vez dicho esto, estoy seguro de por qué se canceló la opción # 2 ya. En realidad, estamos haciendo algo similar a esto. Tal vez estoy confundido por los números, pero lo que está mencionando debe ser nada para SQL2K a sudar.

Incluso si se calcula la distancia en línea de zip para comprimir en los EE.UU., hay sólo ~ 2 mil millones filas. Sí, es mucho, pero es roughtly estática, podría ser fragmentada si es lento, etc.

SELECT de 350K filas (el ejemplo de Nueva York) no tomará 6 minutos si ordena la tabla y de índice SOURCEZIP (ALTER TABLE .. ORDER BY (SOURCEZIP)) en MySQL. Debe tener sólo una fracción de segundo ... El ALTER llevará mucho tiempo (o que podría crear la tabla en ese orden) -. Pero ya que es una tabla estática que sería bien vale nada

¿Está utilizando SQL 2008? Si es así las nuevas características de datos espaciales podrían ser justo lo que está buscando aquí. Puede encontrar las coordenadas dentro del alcance del otro con tanta facilidad como el uso de un "me gusta" en comparación cadenas.

http://www.microsoft.com/sqlserver /2008/en/us/spatial-data.aspx

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top