Selon les documents Microsoft, les index spatiaux seront utilisés avec les types géographiques sur les méthodes suivantes lorsqu'ils apparaissent au début d'un prédicat de comparaison avec une WHERE
clause:
STIntersects
STDistance
STEquals
Seules les méthodes des types de géométrie (liste restreinte) déclencheront l'utilisation de l'index spatial dans JOIN ... ON
, donc changez votre code à utiliser WHERE geog1.STIntersects(geog2) = 1
et cela devrait améliorer la vitesse.
Je recommande également de prendre des conseils dans la réponse de g2server et d'ajouter ce qui suit pour le filtrage et ajouter un index spatial dessus
ALTER TABLE [dbo].[T_POLYGON] ADD SimplePolysGeog AS
([geography]::STGeomFromWKB([geometry]::STGeomFromWKB([COORD].[STAsBinary](),
[COORD].[STSrid])
.STEnvelope().STAsBinary(),(4326))) PERSISTED
vous pourriez alors avoir une requête comme la suivante (j'ai écrit ce post rapidement et je n'ai pas encore testé, c'est juste quelque chose à essayer car j'ai vu que votre requête et les réponses les plus élevées utilisent JOIN ON spatial op = 1 qui n'utilisera pas de indice spatial):
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
Pour info: ce qui précède ne fonctionne pas si SimplePolysGeog
finissent par se chevaucher (comme dans une épingle peut être dans deux geogs simplifiés, il suffit de l'exécuter sur les personnes dans les circonscriptions dans un état et puisque les polys normaux partagent la frontière, les boîtes de délimitation se chevauchent), donc dans la plupart des utilisations cas, il générera une erreur indiquant que la sous-requête a renvoyé plusieurs résultats.
De la vue d'ensemble des index spatiaux de MS Docs :
Méthodes de géographie prises en charge par les index spatiaux
Dans certaines conditions, les index spatiaux prennent en charge les méthodes de géographie orientées ensemble suivantes: STIntersects (), STEquals () et STDistance (). Pour être prises en charge par un index spatial, ces méthodes doivent être utilisées dans la clause WHERE d'une requête et elles doivent se produire dans un prédicat de la forme générale suivante:
geography1.method_name (geography2) comparaison_operatorvalid_number
Pour renvoyer un résultat non nul, geography1 et geography2 doivent avoir le même identifiant de référence spatiale (SRID) . Sinon, la méthode renvoie NULL.
Les index spatiaux prennent en charge les formes de prédicat suivantes:
Requêtes qui utilisent des index spatiaux
Les index spatiaux ne sont pris en charge que dans les requêtes qui incluent un opérateur spatial indexé dans la clause WHERE. Par exemple, la syntaxe telle que:
[spatial object].SpatialMethod([reference spatial object]) [ = | < ] [const literal or variable]
L'optimiseur de requêtes comprend la commutativité des opérations spatiales (cela @a.STIntersects(@b) = @b.STInterestcs(@a)
). Cependant, l'index spatial ne sera pas utilisé si le début d'une comparaison ne contient pas l'opérateur spatial (par exemple, WHERE 1 = spatial op
n'utilisera pas l'index spatial). Pour utiliser l'index spatial, réécrivez la comparaison (par exemple WHERE spatial op = 1
).
...
La requête suivante fonctionnera en cas de SimplePolysGeogs
chevauchement:
;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