2012-01-26 77 views
0

我有2個表:使這一空間查詢更有效

tZipCodeNoCityZipCodePointGeographyMBLPositionLatitudeLongitude

在此查詢我發現最接近郵編我的位置。這是「可憐的人」地理編碼:)

如何寫這個查詢,所以我不必這樣做SELECT TOP 1內聯? 它甚至150設備(如20秒)相當緩慢

我必須包括150英里半徑進入這個子選擇獲得更快

SELECT LastPositions.DeviceId, P.Description, P.Latitude, P.Longitude, P.Speed, P.DeviceTime, 
(
SELECT TOP 1 ZC.ZipCode 
FROM dbo.tZipCodeNoCity ZC 
WHERE ZC.PointGeography.STDistance(geography::STPointFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326)) < 150 * 1609.344 
ORDER BY ZC.PointGeography.STDistance(geography::STPointFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326)) 
) 
      FROM dbo.MBLPosition P 
      INNER JOIN 
      (
       SELECT D.DeviceId, MAX(P.PositionKey) LastPositionKey 
       FROM dbo.MBLPosition P 
       INNER JOIN IDATTApplication.dbo.MBLDevice D ON P.DeviceKey = D.DeviceKey 
       GROUP BY D.DeviceId 
      ) LastPositions ON P.PositionKey = LastPositions.LastPositionKey 

回答

0

在一個項目中,我在大約12年前的工作,我跑沿着這些路線查詢,以減少可能的名單做的實際距離計算前:

WHERE zip.lat < my.lat + 0.5 && zip.lat > my.lat - 0.5 
    && zip.long < my.long + 0.5 && zip.long > my.long - 0.5 

該子集中,我計算出兩點之間的實際距離和排序就可以了。您必須根據需要調整「0.5」部分,以獲得足夠大的盒子以確保您會受到打擊。

我想象有一個比STPointFromText更好的方法來創建你的點對象。你能用STPointFromWKB嗎?你可以轉換成geography類型嗎?

有關通過SET創建點的示例,請參閱this page

DECLARE @p geography; 
SET @p = geography::STGeomFromText('POINT(' + CAST(P.Longitude AS VARCHAR(20)) + ' ' + CAST(P.Latitude AS VARCHAR(20)) + ')', 4326); 

SELECT TOP 1 ZC.ZipCode 
FROM dbo.tZipCodeNoCity ZC 
WHERE ZC.PointGeography.STDistance(@p)) < 150 * 1609.344 
ORDER BY ZC.PointGeography.STDistance(@p)) 
+0

這是一種臨時解決方案,我不想在MBLPosition上添加地理欄,因爲所有CRUD都是通過實體框架ORM完成的,並且沒有空間支持。我在想也許某種MIN()查詢可能然後加入 – katit 2012-01-26 22:48:09