Согласно документам Microsoft, пространственные индексы будут использоваться с типами географии в следующих методах, когда они появляются в начале предиката сравнения с WHERE
предложением:
STIntersects
STDistance
STEquals
Только методы с геометрическими типами (ограниченный список) будут инициировать использование пространственного индекса JOIN ... ON
, поэтому измените код, который будет использоваться, WHERE geog1.STIntersects(geog2) = 1
и это должно повысить скорость.
Я также рекомендую принять совет в ответе g2server и добавить следующее для фильтрации и добавить пространственный индекс на него
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
тогда вы могли бы получить запрос, подобный следующему (я написал это сообщение быстро и еще не проверял, это просто что-то попробовать, потому что я видел, что ваш запрос и ответы с наибольшим количеством ответов используют JOIN ON пространственный op = 1, который не будет использовать пространственный индекс):
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
К вашему сведению: вышеупомянутое не работает, если в SimplePolysGeog
конечном итоге перекрывается (как в выводе может быть в двух упрощенных геог, просто запустил это на людях на участках в состоянии и так как обычные границы полиса, ограничивающие прямоугольники перекрываются), поэтому в большинстве случаев В некоторых случаях будет выдано сообщение о том, что подзапрос вернул более одного результата.
Из обзора пространственных индексов MS Docs :
Географические методы, поддерживаемые пространственными индексами
При определенных условиях пространственные индексы поддерживают следующие ориентированные на множество географические методы: STIntersects (), STEquals () и STDistance (). Для поддержки пространственного индекса эти методы должны использоваться в предложении WHERE запроса, и они должны встречаться в предикате следующей общей формы:
geography1.method_name (geography2) comparison_operatorvalid_number
Чтобы вернуть ненулевой результат, geography1 и geography2 должны иметь одинаковый идентификатор пространственной привязки (SRID) . В противном случае метод возвращает NULL.
Пространственные индексы поддерживают следующие формы предикатов:
Запросы, которые используют пространственные индексы
Пространственные индексы поддерживаются только в запросах, которые включают индексированный пространственный оператор в предложении WHERE. Например, такой синтаксис, как:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
Оптимизатор запросов понимает коммутативность пространственных операций (то есть @a.STIntersects(@b) = @b.STInterestcs(@a)
). Однако пространственный индекс не будет использоваться, если начало сравнения не содержит пространственный оператор (например WHERE 1 = spatial op
, не будет использовать пространственный индекс). Чтобы использовать пространственный индекс, перепишите сравнение (например WHERE spatial op = 1
).
...
Следующий запрос будет работать в случае SimplePolysGeogs
наложения:
;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