2016-07-14 73 views
2

我有一個表點有一列的點類型GEOGRAPHY。我運行這段代碼獲得的最近點:選擇最近的點sql server空間

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; 

積分表有這個索引:

CREATE SPATIAL INDEX SpatialIndex ON Points (Point); 

不幸的是,查詢是相當緩慢。有什麼我可以改進,使其更快(索引和/或查詢明智)?

PS:

我也打了這方面的一些口味:

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]; 

的表現依然不能接受的。

回答

0

微軟自己在MSDN上的文章提出了一些改進措施,可以確保「最近鄰居」查詢使用空間索引。主要的一點是我沒有在WHERE子句中使用STDistance來限制距離(沒有這個距離,它不能以任何方式過濾)。

嘗試應用並查看是否可以提高性能。如果沒有參考文章本身的進一步提示。

MSDN Nearest Neighbor

編輯

首先,你可以按如下簡化查詢創建點的過程:

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

其次,它可能不會有所作爲,但是你可以聲明你的空間索引爲HHHH,最多16個單元格(你可以選擇一個)。在一天結束時,作爲一個奇點,它只會在最低級別的索引中創建一條記錄,但這取決於是否要在列中混合使用空間數據類型。

第三,我跑了幾次測試,你應該很容易就能得到一秒鐘的結果。我使用以下查詢:

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

我的結果比1秒快很多。如果我省略WHERE子句,則時間大約減慢1500%(隨着數據集大小而增加/減少)。但是這比你10-12秒的結果還要快。

您可以驗證您的空間索引是否有效?如果沒有,請嘗試使用WITH(INDEX(SpatialIndex))提示。如果仍然不起作用,您可以上傳您的查詢執行計劃嗎?

+0

謝謝。當我按照文章中的建議介紹WHERE子句時,爲了顯然強制使用空間索引,查詢執行速度更慢。 – cs0815

+0

@csetzkorn表格的大小(以行爲單位)和你現在得到的次數是多少? –

+0

約250萬行... – cs0815