Secondo i documenti Microsoft, gli indici spaziali verranno utilizzati con i tipi di geografia sui seguenti metodi quando compaiono all'inizio di un predicato di confronto con una WHERE
clausola:
STIntersects
STDistance
STEquals
Solo i metodi dei tipi di geometria (elenco limitato) attiveranno l'uso dell'indice spaziale JOIN ... ON
, quindi cambia il codice da utilizzare WHERE geog1.STIntersects(geog2) = 1
e ciò dovrebbe migliorare la velocità.
Consiglio anche di dare consigli nella risposta di g2server e aggiungere quanto segue per filtrare e aggiungere l'indice spaziale su di esso
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
potresti quindi avere una query come la seguente (ho scritto questo post rapidamente e non ho ancora testato, questo è solo qualcosa da provare perché ho visto che la tua query e le risposte più alte pubblicate utilizzano JOIN ON spatial op = 1 che non utilizzerà un indice spaziale):
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
Cordiali saluti: Quanto sopra non funziona se SimplePolysGeog
finiscono per sovrapporsi (come in un pin può trovarsi in due geog semplificati, basta eseguirlo su persone in recinti in uno stato e poiché i polys normali condividono il confine, i riquadri di delimitazione si sovrappongono), quindi nella maggior parte degli usi casi, genererà un errore che la query secondaria ha restituito più di un risultato.
Dalla panoramica degli indici spaziali di MS Docs :
Metodi geografici supportati da indici spaziali
In determinate condizioni, gli indici spaziali supportano i seguenti metodi geografici orientati agli insiemi: STIntersects (), STEquals () e STDistance (). Per essere supportati da un indice spaziale, questi metodi devono essere utilizzati all'interno della clausola WHERE di una query e devono verificarsi all'interno di un predicato del seguente modulo generale:
geography1.method_name (geography2) comparison_operatorvalid_number
Per restituire un risultato non nullo, geography1 e geography2 devono avere lo stesso identificatore di riferimento spaziale (SRID) . Altrimenti, il metodo restituisce NULL.
Gli indici spaziali supportano i seguenti moduli predicati:
Query che utilizzano gli indici spaziali
Gli indici spaziali sono supportati solo nelle query che includono un operatore spaziale indicizzato nella clausola WHERE. Ad esempio sintassi come:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
Query Optimizer comprende la commutatività delle operazioni spaziali (quella @a.STIntersects(@b) = @b.STInterestcs(@a)
). Tuttavia, l'indice spaziale non verrà utilizzato se l'inizio di un confronto non contiene l'operatore spaziale (ad esempio WHERE 1 = spatial op
non utilizzerà l'indice spaziale). Per utilizzare l'indice spaziale, riscrivere il confronto (ad esempio WHERE spatial op = 1
).
...
La seguente query funzionerà se si SimplePolysGeogs
sovrappongono:
;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