Według dokumentów Microsoft indeksy przestrzenne będą używane z typami geograficznymi w następujących metodach, gdy pojawią się one na początku predykatu porównania z WHERE
klauzulą:
STIntersects
STDistance
STEquals
Tylko metody typów geometrii (lista zastrzeżona) wyzwalają użycie indeksu przestrzennego w JOIN ... ON
, więc zmień kod na używany WHERE geog1.STIntersects(geog2) = 1
i to powinno poprawić prędkość.
Polecam również skorzystanie z porady w odpowiedzi g2server i dodanie poniższych elementów do filtrowania i dodania do niej indeksu przestrzennego
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
możesz mieć takie zapytanie jak poniżej (napisałem ten post szybko i jeszcze go nie testowałem, to jest po prostu coś do wypróbowania, ponieważ widziałem, że twoje zapytanie i najwyższe opublikowane odpowiedzi używają JOIN ON spatial op = 1, który nie użyje indeks przestrzenny):
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: Powyższe nie działa, jeśli SimplePolysGeog
skończy się nakładanie (jak w szpilce może być w dwóch uproszczonych geogach, po prostu uruchomiłem to na ludziach w obwodzie w stanie, a ponieważ normalne polisy mają granicę, pola ograniczające się na siebie nakładają), więc w większości przypadków przypadki wyrzuci błąd, że podzapytanie zwróciło więcej niż jeden wynik.
Z przeglądu indeksów przestrzennych MS Docs :
Metody geograficzne obsługiwane przez indeksy przestrzenne
Pod pewnymi warunkami indeksy przestrzenne obsługują następujące metody geograficzne zorientowane na zestaw: STIntersects (), STEquals () i STDistance (). Aby zapewnić obsługę indeksu przestrzennego, metody te muszą być używane w klauzuli WHERE zapytania i muszą występować w predykacie o następującej formie ogólnej:
geography1.method_name (geography2) Porównanie_operatorvalid_number
Aby zwrócić wynik inny niż zero, geografia1 i geografia2 muszą mieć ten sam identyfikator odniesienia przestrzennego (SRID) . W przeciwnym razie metoda zwraca NULL.
Indeksy przestrzenne obsługują następujące formy predykatów:
Zapytania korzystające z indeksów przestrzennych
Indeksy przestrzenne są obsługiwane tylko w zapytaniach, które zawierają indeksowanego operatora przestrzennego w klauzuli WHERE. Na przykład składnia, taka jak:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
Optymalizator zapytań rozumie komutatywność operacji przestrzennych (tego @a.STIntersects(@b) = @b.STInterestcs(@a)
). Indeks przestrzenny nie będzie jednak stosowany, jeśli początek porównania nie zawiera operatora przestrzennego (na przykład WHERE 1 = spatial op
nie użyje indeksu przestrzennego). Aby użyć indeksu przestrzennego, przepisz porównanie (na przykład WHERE spatial op = 1
).
...
Następujące zapytanie będzie działać, jeśli się SimplePolysGeogs
pokrywają:
;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