Según los documentos de Microsoft, los índices espaciales se usarán con los tipos de geografía en los siguientes métodos cuando aparecen al comienzo de un predicado de comparación con una WHERE
cláusula:
STIntersects
STDistance
STEquals
Solo los métodos de tipos de geometría (lista restringida) activarán el uso del índice espacial JOIN ... ON
, así que cambie su código para usarlo WHERE geog1.STIntersects(geog2) = 1
y eso debería mejorar la velocidad.
También recomiendo tomar consejos en la respuesta de g2server y agregar lo siguiente para filtrar y agregar índice espacial en él
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
entonces podría tener una consulta como la siguiente (escribí esta publicación rápidamente y aún no la he probado, esto es solo algo para probar porque vi que su consulta y las respuestas más altas publicadas usan JOIN ON espacial op = 1 que no usará un índice espacial):
SELECT
(SELECT p2.polygon_id
FROM T_Polygon p2
WHERE p2.coords.STIntersects(t.coords) = 1),
t.pin_id
FROM T_PIN t
WHERE
(SELECT t.coords.STIntersects(p.coords)
FROM T_POLYGON p
WHERE t.coords.STIntersects(p.SimplePolysGeog) = 1) = 1
FYI: Lo anterior no funciona si SimplePolysGeog
termina superpuesto (como en un pin puede estar en dos geogs simplificados, solo ejecuté esto en personas en recintos en un estado y dado que los polys normales comparten límites, los cuadros delimitadores se superponen), por lo que en la mayoría de los usos casos, arrojará un error que la subconsulta arrojó más de un resultado.
Del resumen de índices espaciales de MS Docs :
Métodos de geografía soportados por índices espaciales
Bajo ciertas condiciones, los índices espaciales admiten los siguientes métodos de geografía orientados a conjuntos: STIntersects (), STEquals () y STDistance (). Para ser soportados por un índice espacial, estos métodos deben usarse dentro de la cláusula WHERE de una consulta, y deben ocurrir dentro de un predicado de la siguiente forma general:
geography1.method_name (geography2) compare_operatorvalid_number
Para devolver un resultado no nulo, geography1 y geography2 deben tener el mismo Identificador de referencia espacial (SRID) . De lo contrario, el método devuelve NULL.
Los índices espaciales admiten las siguientes formas de predicado:
Consultas que usan índices espaciales
Los índices espaciales solo se admiten en consultas que incluyen un operador espacial indexado en la cláusula WHERE. Por ejemplo, sintaxis como:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
El optimizador de consultas comprende la conmutatividad de las operaciones espaciales (eso @a.STIntersects(@b) = @b.STInterestcs(@a)
). Sin embargo, el índice espacial no se usará si el comienzo de una comparación no contiene el operador espacial (por ejemplo WHERE 1 = spatial op
, no usará el índice espacial). Para usar el índice espacial, reescriba la comparación (por ejemplo WHERE spatial op = 1
).
...
La siguiente consulta funcionará si se SimplePolysGeogs
superpone:
;WITH cte AS
(
SELECT T_PIN.PIN_ID,
T_POLYGON.POLYGON_ID,
T_POLYGON.COORD
FROM T_PIN
INNER JOIN T_POLYGON
ON T_PIN.COORD.STIntersects(T_POLYGON.SimplePolysGeog) = 1
)
SELECT COUNT(*)
FROM T_PIN
INNER JOIN cte
ON T_PIN_PIN_ID = cte.PIN_ID
where cte.[COORD].STIntersects(T_PIN.COORD) = 1