Делая этот пространственный запрос более эффективным - PullRequest
0 голосов
/ 27 января 2012

У меня есть 2 таблицы:

tZipCodeNoCity с ZipCode и PointGeography и MBLPosition с Latitude и Longitude

В этом запросе я нахожуближайший ZipCode к моим позициям.Это геокодирование "бедняги":)

Как мне написать этот запрос, чтобы мне не пришлось делать это SELECT TOP 1 inline?Это довольно медленно, даже с 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

1 Ответ

0 голосов
/ 27 января 2012

В проекте, над которым я работал около 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.

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))
...