Tabelle T_PIN
hat 300.000 Stifte und T_POLYGON
hat 36.000 Polygone. T_PIN
hat diesen Index:
CREATE SPATIAL INDEX [T_PIN_COORD] ON [dbo].[T_PIN]
(
[Coord]
)USING GEOGRAPHY_GRID
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];
T_POLYGON
hat:
CREATE SPATIAL INDEX [T_POLYGON_COORD] ON [dbo].[T_POLYGON]
(
[COORD]
)USING GEOGRAPHY_GRID
WITH (GRIDS =(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH),
CELLS_PER_OBJECT = 128, PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF,
SORT_IN_TEMPDB = OFF, DROP_EXISTING = OFF, ONLINE = OFF,
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON)
ON [PRIMARY];
Eine Abfrage zum Ermitteln des Schnittpunkts von T_PIN
und T_POLYGON
die Ausführung dauert mehr als 45 Minuten:
SELECT COUNT(*)
FROM T_PIN
INNER JOIN T_POLYGON
ON T_PIN.Coord.STIntersects(T_POLYGON.COORD) = 1;
Das Ergebnis sind 4.438.318 Zeilen.
Wie kann ich diese Abfrage beschleunigen?
Antworten:
Überprüfen Sie zunächst anhand des Abfrageausführungsplans, ob ein räumlicher Index verwendet wird, und prüfen Sie, ob ein Element für die Suche nach Clustered Index (Spatial) vorhanden ist.
Angenommen, es wird verwendet, können Sie versuchen, einen sekundären / vereinfachten Filter basierend auf einem Begrenzungsrahmen mit vereinfachten Polygonen hinzuzufügen, um zuerst zu prüfen. Übereinstimmungen mit diesen vereinfachten Polygonen könnten dann durch den Primärfilter geführt werden, um die Endergebnisse zu erhalten.
1) Fügen Sie der Tabelle [dbo] eine neue Geografie- und Geometriespalte hinzu. [T_POLYGON] -Tabelle:
2) Erstellen Sie die Begrenzungsrahmen-Polygone (dies beinhaltet eine anfängliche Konvertierung in Geometrie, um STEnvelope () zu nutzen):
3) Erstellen Sie einen räumlichen Index für die vereinfachte Geografiespalte
4) Holen Sie sich die Schnittpunkte für diese vereinfachte Geografiespalte und filtern Sie erneut nach den übereinstimmenden Geografiedatentypen. Etwa so etwas:
BEARBEITEN : Sie können (1) und (2) durch diese berechnete, persistente Spalte ersetzen. Dank an Paul White für den Vorschlag.
quelle
Abfragen wie diese dauern aufgrund der Komplexität der Polygone oft lange. Ich habe gesehen, dass komplexe Küsten (zum Beispiel) ewig brauchen, um Punkte zu testen, die nahe an ihren Grenzen liegen, und viele Ebenen zoomen müssen, um festzustellen, ob sich ein Punkt innerhalb oder außerhalb befindet.
... also könntest du es versuchen
.Reduce()
, die Polygone zu verwenden, um zu sehen, ob das hilft.Weitere Informationen zu dieser Funktion finden Sie unter http://msdn.microsoft.com/en-us/library/cc627410.aspx
quelle
Laut Microsoft-Dokumenten werden räumliche Indizes mit Geografietypen für die folgenden Methoden verwendet, wenn sie am Anfang eines Vergleichsprädikats mit einer
WHERE
Klausel angezeigt werden:STIntersects
STDistance
STEquals
Nur die Methoden der Geometrietypen (eingeschränkte Liste) lösen die Verwendung des räumlichen Index in aus
JOIN ... ON
. Ändern Sie daher den zu verwendenden CodeWHERE geog1.STIntersects(geog2) = 1
die Geschwindigkeit zu verbessern.Ich empfehle außerdem, sich in der Antwort von g2server beraten zu lassen und Folgendes zum Filtern hinzuzufügen und einen räumlichen Index hinzuzufügen
Sie könnten dann eine Abfrage wie die folgende haben (ich habe diesen Beitrag schnell geschrieben und noch nicht getestet. Dies ist nur ein Versuch, da ich gesehen habe, dass Ihre Abfrage und die am höchsten geposteten Antworten JOIN ON räumlich op = 1 verwenden, wobei a nicht verwendet wird räumlicher Index):
Zu Ihrer Information: Das oben genannte funktioniert nicht, wenn
SimplePolysGeog
Ihrer Information Genannte Ende überlappt (wie in einem Pin in zwei vereinfachten Geogs, kann dies nur für Personen in Bezirken in einem Bundesstaat ausgeführt werden und da sich normale Polys die Grenzen teilen, überlappen sich die Begrenzungsrahmen), so dass sie in den meisten Fällen verwendet werden In diesen Fällen wird der Fehler ausgegeben, dass die Unterabfrage mehr als ein Ergebnis zurückgegeben hat.Aus der Übersicht über die räumlichen Indizes von MS Docs :
Die folgende Abfrage funktioniert bei
SimplePolysGeogs
Überlappung:quelle