使此空间查询更有效

时间:2012-01-26 22:09:52

标签: sql-server tsql geospatial

我有两张桌子:

tZipCodeNoCityZipCodePointGeographyMBLPosition LatitudeLongitude

在这个查询中,我找到了最接近我的位置的ZipCode。它是“穷人”地理编码:)

如何编写此查询,以便我不必执行此操作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

1 个答案:

答案 0 :(得分: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))