Optimización de la geometría. Consulta Intersect

8

Estoy intentando mover rutinas de geoprocesamiento simples de procesos basados ​​en ESRI a SQL Server. Mi suposición es que será mucho más eficiente. Para mi prueba inicial, estoy trabajando en una rutina de intersección para asociar datos lineales superpuestos.

En mi tabla WCASING tengo 1610 registros. Estoy tratando de asociar estas tripas con sus redes principales asociadas. Tengo ~ 277,000 platos principales. Tengo ~ 1.600 tripas.

Estoy ejecutando la consulta a continuación para tener una idea general de cuánto tiempo llevará encontrar coincidencias individuales. Esta consulta devolvió 5 intersecciones válidas en 40 segundos.

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN]
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

Mis preguntas principales

¿Se procesará más rápido según el orden de búsqueda?

  • Encontrar 'A' dentro de 'B' vs
  • Encontrar 'B' dentro de 'A'
  • El retorno inicial de 5 registros de estos conjuntos de datos es que no importa

¿Se procesará esto más rápido si primero amortiguo para limitar a un conjunto principal más pequeño y luego busco?

¿Puedo usar SQL Server Tuning para trabajar con consultas basadas en geometría?

SELECT WCASING.OBJECTID AS CasingOBJECTID,
    WPUMPPRESSUREMAIN.OBJECTID AS MainObjectID, WCASING.UFID AS UFID,
    WPUMPPRESSUREMAIN_IPS.UFID AS MainUFID, WCASING.SHAPE
INTO WCASING_INTDefsV6
FROM WCASING with (index([FDO_ShapeWC])) 
    INNER JOIN [WPUMPPRESSUREMAIN_IPS] ON 
        [WPUMPPRESSUREMAIN_IPS].Shape.STIntersects(WCASING.SHAPE) = 1

Esta nueva consulta tiene definiciones mejoradas.

  • Ahora ambas tablas tienen índices espaciales
  • Anteriormente, la tabla de revestimiento (más pequeña) no tenía un índice espacial
    • Sí contenía un índice no agrupado

La consulta también tiene la instrucción with index.

La nueva consulta tomó 37 minutos. La consulta anterior tardó 44 minutos.

Esperaba mejores resultados y seguiré probando.

Rick Monteiro
fuente
1
divertido, ¿no?
DPSSpatial
Es impresionante. He estado en una nueva posición durante un año, trabajando con conjuntos de datos muy grandes y la curva de aprendizaje con SQL Server ha sido la parte más agradable. Todavía soy un novato en muchos sentidos, pero he aprendido algunas cosas interesantes.
Rick Monteiro
1
¡Hemos estado usando datos y funciones espaciales de SQL Server para nuestro análisis durante casi 2 años y no regresaremos pronto!
DPSEspacial
Esperaría que forzar el índice en la tabla más grande (red) tendría un mejor rendimiento.
MickyT

Respuestas:

7

Supongo que está utilizando Geometrías, pero las metodologías siguen siendo prácticamente las mismas.

Al ajustar consultas espaciales, estos son los pasos que tomo

  1. Este es el paso más importante . Compruebe que los índices son adecuados para la tabla. Si tiene SQL Server 2012+, le sugiero que use la GRIDACIÓN AUTOMÁTICA. Esto te da una cuadrícula más fina. Asegúrese de que las extensiones cubran los datos y no se extiendan demasiado lejos de ellos. Si indexa polígonos o líneas, intente y determine un valor sensible de Celdas por objeto. El resumen de indexación espacial es bastante bueno para explicarlo.

  2. Escriba la consulta en su forma más simple primero. Verifique el Plan de ejecución estimado para asegurarse de que se está utilizando el índice espacial que espera. Ejecute la consulta y obtenga los tiempos y las estadísticas de E / S. Un plan de ejecución real también sería útil. Esta será su línea de base.

  3. Pruebe las variaciones de la consulta, incluido el intercambio del orden de las geometrías en la comparación de geometría, etc. Recopile estadísticas para cada una.

  4. Intenta dividir la consulta en partes más pequeñas si es posible (divide y vencerás). A veces esto da como resultado una ejecución general más rápida.

  5. Si todo lo demás falla y no puede obtener sus consultas para usar el índice espacial, use la sugerencia de índice. Este es un último recurso y potencialmente significa que puede haber problemas con la indexación en la tabla. Dicho esto, el optimizador no siempre lo hace bien.

Mire los planes de ejecución y pase un poco de tiempo tratando de entenderlos. Son tu amigo de verdad. También hay herramientas que las hacen más fáciles de interpretar. El que uso es SQL Sentry .

En cuanto a la consulta que publicaste, creo que será la que tenga mejor rendimiento, pero aquí hay una variación que quizás quieras probar. Además, el operador TOP afectará la forma en que se construye el plan de ejecución, por lo que probablemente no obtendrá una buena comparación entre los diferentes métodos.

SELECT c.[OBJECTID] As CasingOBJECTID, 
    x.[OBJECTID] AS MainObjectID, 
    c.[Shape]
FROM [WCASING] c -- Smallest Table
    CROSS APPLY (
        -- This query is essentially done for each casing
        SELECT p.[OBJECTID]
        FROM [dbo].[WPUMPPRESSUREMAIN] p -- Largest table
        WHERE p.[Shape].STIntersects(c.[Shape]) = 1 -- should use the pressure main spatial index
        ) x
MickyT
fuente
1

Lo que he encontrado acelera más estas consultas de intersección es forzar el índice espacial:

En una vista que entrego a BI que cruza ~ 280,000 puntos de dirección con ~ 300 polígonos de límite, forzo el uso del índice espacial del punto de dirección:

...

FROM [dpsdata].[Address_Master] as am with (index(SIndx_AddrMsterIC))
  left outer join [dpsdata].[SchoolBoundaries_All_Projected] as sbp
  on (am.shape.STIntersects(sbp.shape) =1)

(Suponiendo que ambas tablas tengan índices espaciales construidos ya, por supuesto ...)

Esto demora cerca de 1 minuto en ejecutarse, en vez de varios minutos.

En su caso, algo como esto debería funcionar:

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN] with (index(PK__WPUMPPRE__E458E6E7F06C9A87)) 
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1
DPSSpacial
fuente
Intenté esto No funcionó de la manera que intenté implementarlo. "SELECT Top 5 WCASING.OBJECTID AS CasingOBJECTID, WPUMPPRESSUREMAIN.OBJECTID_1 AS MainObjectID, WCASING.UFID, WCASING.SHAPE con (índice (PK__WPUMPPRE__E458E6E7F06C9A87)) EN WCASING_INTDefs_V2 DE WCASING INNER JOIN WPUMPPRESSUREMAIN EN WPUMPPRESSUREMAIN.Shape.STIntersects (WCASING.SHAPE) = 1 "devuelve un error. "Mensaje 319, Nivel 15, Estado 1, Línea 1 Sintaxis incorrecta cerca de la palabra clave 'con'. Si esta declaración es una expresión de tabla común, ..."
Rick Monteiro
No he usado la opción 'con' antes. ¿Es esto específico de un campo o de la instrucción From en general? ¿Puedo tener dos declaraciones 'con' una para cada tabla? Segunda pregunta, ¿debería ser el índice un índice espacial?
Rick Monteiro
1a) 'with' se usa en este caso en la declaración FROM y 1b) No sé si funcionará si usa 2 'with' declaraciones ... 2) Solo he intentado esto con un índice espacial
DPSEspacial
1
Actualicé mi respuesta para mostrar cómo podría usar su índice espacial en la consulta en su publicación original ...
DPSSpatial
1
@RichardMonteiro lo siento, olvidé el 'con' antes del índice espacial en mi respuesta usando su ejemplo ... He actualizado.
DPSSpatial