Optimieren der Geometry.STIntersect-Abfrage


8

Ich versuche, einfache Geoverarbeitungsroutinen von ESRI-basierten Prozessen auf SQL Server zu verschieben. Ich gehe davon aus, dass es weitaus effizienter sein wird. Für meinen ersten Test arbeite ich an einer Schnittroutine, um überlappende lineare Daten zuzuordnen.

In meiner WCASING-Tabelle habe ich 1610 Datensätze. Ich versuche, diese Gehäuse mit dem zugehörigen Netz zu verbinden. Ich habe ~ 277.000 Netze. Ich habe ~ 1.600 Gehäuse.

Ich führe die folgende Abfrage aus, um einen allgemeinen Eindruck davon zu bekommen, wie lange es dauern wird, einzelne Übereinstimmungen zu finden. Diese Abfrage ergab 5 gültige Schnittpunkte in 40 Sekunden.

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN]
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

Meine Hauptfragen;

Wird dieser Vorgang je nach Suchreihenfolge schneller ablaufen?

  • Finden von 'A' innerhalb von 'B' vs.
  • Finden von 'B' innerhalb von 'A'
  • Die erste Rückgabe von 5 Datensätzen aus diesen Datensätzen ist, dass dies keine Rolle spielt

Wird dieser Prozess schneller, wenn ich zuerst puffere, um mich auf einen kleineren Hauptsatz zu beschränken, und dann suche?

Kann ich SQL Server-Optimierung verwenden, um mit geometriebasierten Abfragen zu arbeiten?

SELECT WCASING.OBJECTID AS CasingOBJECTID,
    WPUMPPRESSUREMAIN.OBJECTID AS MainObjectID, WCASING.UFID AS UFID,
    WPUMPPRESSUREMAIN_IPS.UFID AS MainUFID, WCASING.SHAPE
INTO WCASING_INTDefsV6
FROM WCASING with (index([FDO_ShapeWC])) 
    INNER JOIN [WPUMPPRESSUREMAIN_IPS] ON 
        [WPUMPPRESSUREMAIN_IPS].Shape.STIntersects(WCASING.SHAPE) = 1

Diese neue Abfrage hat die Definitionen verbessert.

  • Jetzt haben beide Tabellen räumliche Indizes
  • Zuvor hatte die Gehäusetabelle (kleiner) keinen räumlichen Index
    • Es enthielt einen nicht gruppierten Index

Die Abfrage enthält auch die Anweisung with index.

Die neue Abfrage dauerte 37 Minuten. Die alte Abfrage dauerte 44 Minuten.

Ich hatte auf bessere Ergebnisse gehofft und werde weiter testen.


1
Spaß, nicht wahr?
DPSSpatial

Es ist toll. Ich bin seit einem Jahr in einer neuen Position und habe mit sehr großen Datenmengen gearbeitet. Die Lernkurve mit SQL Server hat mir am meisten Spaß gemacht. Ich bin in vielerlei Hinsicht immer noch ein Noob, aber ich habe ein paar coole Sachen gelernt.
Rick Monteiro

1
Wir verwenden seit fast 2 Jahren räumliche Daten und Funktionen von SQL Server für unsere Analyse und kehren nicht so schnell zurück !!!
DPSSpatial

Ich würde erwarten, dass das Erzwingen des Index für die größere Tabelle (Netz) eine bessere Leistung hat.
MickyT

Antworten:


7

Ich gehe davon aus, dass Sie Geometrien verwenden, aber die Methoden bleiben größtenteils gleich.

Wenn ich räumliche Abfragen optimiere, sind dies die Schritte, die ich unternehme

  1. Dies ist der wichtigste Schritt . Überprüfen Sie, ob die Indizes für die Tabelle geeignet sind. Wenn Sie SQL Server 2012+ haben, würde ich vorschlagen, dass Sie das AUTO GRID verwenden. Dies gibt Ihnen ein feineres Gitter. Stellen Sie sicher, dass die Bereiche die Daten abdecken und nicht zu weit davon entfernt sind. Wenn Sie Polygone oder Linien indizieren, versuchen Sie, einen sinnvollen Wert für Zellen pro Objekt zu ermitteln. Die räumliche Indizierungsübersicht kann dies recht gut erklären.

  2. Schreiben Sie die Abfrage zuerst in ihrer einfachsten Form. Überprüfen Sie den geschätzten Ausführungsplan, um sicherzustellen, dass der erwartete räumliche Index verwendet wird. Führen Sie die Abfrage aus und rufen Sie die Timings und E / A-Statistiken ab. Ein tatsächlicher Ausführungsplan wäre ebenfalls hilfreich. Dies wird Ihre Basis sein.

  3. Probieren Sie Variationen der Abfrage aus, einschließlich des Austauschs der Reihenfolge der Geometrien im Geometrievergleich usw. Sammeln Sie Statistiken für jede Geometrie.

  4. Versuchen Sie, die Abfrage nach Möglichkeit in kleinere Teile zu unterteilen (teilen und erobern). Manchmal führt dies zu einer insgesamt schnelleren Ausführung.

  5. Wenn alles andere fehlschlägt und Sie Ihre Abfragen nicht dazu bringen können, den räumlichen Index zu verwenden, verwenden Sie den Indexhinweis. Dies ist ein letzter Ausweg und bedeutet möglicherweise, dass Probleme mit der Indizierung in der Tabelle auftreten können. Das heißt, der Optimierer macht es nicht immer richtig.

Schauen Sie sich die Ausführungspläne an und verbringen Sie ein wenig Zeit damit, sie zu verstehen. Sie sind wirklich dein Freund. Es gibt auch Tools, die die Interpretation erleichtern. Ich verwende SQL Sentry .

Was die von Ihnen gepostete Abfrage betrifft, denke ich, dass dies die beste Leistung bringen wird, aber hier ist eine Variante, die Sie vielleicht ausprobieren möchten. Außerdem beeinflusst der TOP-Operator die Art und Weise, wie der Ausführungsplan erstellt wird. Dies bedeutet, dass Sie wahrscheinlich keinen guten Vergleich zwischen verschiedenen Methoden erhalten.

SELECT c.[OBJECTID] As CasingOBJECTID, 
    x.[OBJECTID] AS MainObjectID, 
    c.[Shape]
FROM [WCASING] c -- Smallest Table
    CROSS APPLY (
        -- This query is essentially done for each casing
        SELECT p.[OBJECTID]
        FROM [dbo].[WPUMPPRESSUREMAIN] p -- Largest table
        WHERE p.[Shape].STIntersects(c.[Shape]) = 1 -- should use the pressure main spatial index
        ) x

1

Ich habe festgestellt, dass diese Schnittpunktabfragen am schnellsten den räumlichen Index erzwingen:

In einer Ansicht, die ich an BI übermittle, die ~ 280.000 Adresspunkte mit ~ 300 Grenzpolygonen schneidet, erzwinge ich die Verwendung des Adresspunkt-Raumindex:

...

FROM [dpsdata].[Address_Master] as am with (index(SIndx_AddrMsterIC))
  left outer join [dpsdata].[SchoolBoundaries_All_Projected] as sbp
  on (am.shape.STIntersects(sbp.shape) =1)

(Vorausgesetzt, beide Tabellen haben natürlich schon räumliche Indizes ...)

Der Betrieb dauert fast 1 Minute, nach einigen Minuten.

In Ihrem Fall sollte so etwas funktionieren:

SELECT Top 5 [WCASING].[OBJECTID] As CasingOBJECTID, 
    [WPUMPPRESSUREMAIN].[OBJECTID] AS MainObjectID, [WCASING].[Shape]
FROM [dbo].[WPUMPPRESSUREMAIN] with (index(PK__WPUMPPRE__E458E6E7F06C9A87)) 
    JOIN [WCASING] 
        ON [WCASING].[Shape].STIntersects([WPUMPPRESSUREMAIN].[Shape]) = 1

Ich habe es versucht. Es hat nicht so funktioniert, wie ich es versucht habe. „SELECT Top 5 WCASING.OBJECTID CasingOBJECTID AS, AS WPUMPPRESSUREMAIN.OBJECTID_1 MainObjectID, WCASING.UFID, WCASING.SHAPE mit (index (PK__WPUMPPRE__E458E6E7F06C9A87)) INTO WCASING_INTDefs_V2 FROM WCASING INNER JOIN WPUMPPRESSUREMAIN ON WPUMPPRESSUREMAIN.Shape.STIntersects (WCASING.SHAPE) = 1 "gibt einen Fehler zurück. "Nachricht 319, Ebene 15, Status 1, Zeile 1 Falsche Syntax in der Nähe des Schlüsselworts 'with'. Wenn diese Anweisung ein allgemeiner Tabellenausdruck ist, ..."
Rick Monteiro

Ich habe die Option 'mit' noch nicht verwendet. Ist dies spezifisch für ein Feld oder für die From-Anweisung im Allgemeinen? Kann ich zwei 'with'-Anweisungen für jede Tabelle haben? Zweite Frage, sollte der Index ein räumlicher Index sein?
Rick Monteiro

1a) 'with' wird in diesem Fall in der FROM-Anweisung verwendet und 1b) Ich weiß nicht, ob es funktioniert, wenn Sie 2 'with' -Anweisungen verwenden ... 2) Ich habe dies nur mit einem räumlichen Index versucht
DPSSpatial

1
Ich habe meine Antwort aktualisiert, um zu zeigen, wie Sie Ihren räumlichen Index in der Abfrage in Ihrem ursprünglichen Beitrag verwenden können ...
DPSSpatial

1
@RichardMonteiro Entschuldigung, ich habe das 'mit' vor dem räumlichen Index in meiner Antwort anhand Ihres Beispiels vergessen ... Ich habe aktualisiert.
DPSSpatial
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.