2016-07-14 9 views
2

Ich habe eine Tabelle Punkte mit einer Spalte Punkt des Typs GEOGRAPHY. Ich verwende diesen Code den nächsten Punkt zu erhalten:wählen Sie den nächstgelegenen Punkt SQL-Server räumliche

DECLARE @Wgs84Longitude FLOAT; 
DECLARE @Wgs84Latitude FLOAT; 

DECLARE @Point GEOGRAPHY = Geography::STPointFromText(N'POINT(' 
              + CAST(@Wgs84Longitude AS NVARCHAR(MAX)) 
              + N' ' 
              + CAST(@Wgs84Latitude AS NVARCHAR(MAX)) 
              + N')', 4326); 

SELECT 
    TOP 1 
    * 
FROM Points 
ORDER BY @Point.STDistance(Point) ASC; 

Die Punkte-Tabelle hat diesen Index:

CREATE SPATIAL INDEX SpatialIndex ON Points (Point); 

Leider ist die Abfrage ist ziemlich langsam. Gibt es etwas, was ich verbessern kann, um es schneller zu machen (indexieren und/oder abfragen)?

PS:

ich auch mit einigen Aromen dieser gespielt:

CREATE SPATIAL INDEX SpatialIndex ON [Core].[InternationalPostcodeList](Point) 
USING GEOGRAPHY_GRID 
WITH 
(
--BOUNDING_BOX =(-8.164229, 49.18581, 8.05384, 60.717093) 
     GRIDS=(LEVEL_1 = HIGH,LEVEL_2 = HIGH,LEVEL_3 = HIGH,LEVEL_4 = HIGH) 
    , CELLS_PER_OBJECT = 64 
    , PAD_INDEX = OFF 
    , SORT_IN_TEMPDB = OFF 
    , DROP_EXISTING = OFF 
    , ALLOW_ROW_LOCKS = ON 
    , ALLOW_PAGE_LOCKS = ON 
) ON [PRIMARY]; 

Die Leistung immer noch nicht akzeptabel ist.

Antwort

0

Microsofts eigener Artikel auf MSDN schlägt einige Verbesserungen vor, die Sie vornehmen können, um sicherzustellen, dass eine "Nearest Neighbor" -Abfrage den Spatial Index verwendet. Der Hauptpunkt, der für mich herausragt, ist das Fehlen der Verwendung von STDistance in der WHERE-Klausel, um den Abstand zu begrenzen (ohne den es in keiner Weise filtern kann).

Versuchen Sie, das anzuwenden und sehen Sie, ob das die Leistung verbessert. Wenn nicht, siehe den Artikel selbst für weitere Tipps.

MSDN Nearest Neighbor

EDIT

Zum einen können Sie den Prozess der Erstellung der Punkt in Ihrer Abfrage vereinfachen, wie folgt:

DECLARE @Point GEOGRAPHY = GEOGRAPHY::Point(@latitude, @longitude, @srid); 

Zweitens, ist es wahrscheinlich nicht einen Unterschied machen , aber Sie können Ihren räumlichen Index als HHHH mit maximal 16 Zellen deklarieren (Sie könnten für einen gehen). Am Ende des Tages, wenn es ein singulärer Punkt ist, wird es immer nur einen Index auf der untersten Ebene aufnehmen, aber es hängt davon ab, ob Sie räumliche Datentypen in der Spalte mischen werden.

Drittens habe ich mehrere Tests durchgeführt und Sie sollten leicht in der Lage sein, unter einer Sekunde für ein Ergebnis zu bekommen. Ich habe die folgende Abfrage verwendet:

SELECT TOP 1 
* 
FROM 
Points P 
WHERE P.Point.STDistance(@Point) < (50 * 1609.344) -- 50 miles 
ORDER BY P.Point.STDistance(@Point) 

Meine Ergebnisse waren erheblich schneller als 1 Sekunde. Wenn ich die WHERE-Klausel weggelassen habe, waren die Zeiten um 1500% langsamer (wird mit der Datensatzgröße größer/kleiner). Aber das war immer noch viel schneller als Ihre Ergebnisse von 10-12 Sekunden.

Können Sie überprüfen, ob Ihr räumlicher Index funktioniert? Wenn nicht, versuchen Sie es mit einem WITH (INDEX (SpatialIndex)) Hinweis. Wenn das immer noch nicht funktioniert, können Sie Ihren Abfrageausführungsplan hochladen?

+0

Danke. Wenn ich die WHERE-Klausel wie im Artikel vorgeschlagen einführe, um die Verwendung des räumlichen Index scheinbar zu erzwingen, wird die Abfrage noch langsamer ausgeführt. – cs0815

+0

@csetzkorn Wie groß ist die Tabelle (in Zeilen) und wie hoch sind die aktuellen Zeiten? –

+0

Etwa 2,5 Millionen Zeilen ... – cs0815

Verwandte Themen