我有一个表,我在其中存储纬度/经度坐标,并且我想在其中进行查询,以获取在某个点的距离内的所有记录。
该表有大约 1000 万条记录,并且在 Lat/Long 字段上有一个索引
这不需要很精确。除其他外,我正在考虑 1 度长 == 1 度纬度,我知道这不是真的,但我得到的椭圆足以达到这个目的。
对于下面的示例,假设有问题的点是 [40, 140],而我的半径(以度为单位)为 2 度。
我试过这两种方法:
1) 我创建了一个 UDF 来计算 2 点之间距离的平方,并且我在查询中运行该 UDF。
SELECT Lat, Long FROM Table
WHERE (Lat BETWEEN 38 AND 42)
AND (Long BETWEEN 138 AND 142)
AND dbo.SquareDistance(Lat, Long, 40, 140) < 4
我首先按正方形进行过滤,以加快查询速度并让 SQL 使用索引,然后对其进行细化以仅将落在圆圈内的记录与我的 UDF 匹配。
2)运行查询得到正方形(与以前相同,但没有最后一行),将所有这些记录提供给我的 ASP.Net 代码,并在 ASP.Net 端计算圆(同样的想法,计算平方保存 Sqrt 调用的距离,并与我的半径的平方进行比较)。
令我惊讶的是,在 .Net 端计算圆的速度比使用 UDF 快 10 倍左右,这让我相信我在使用该 UDF 时做错了什么......
这是我正在使用的代码:
CREATE FUNCTION [dbo].[SquareDistance]
(@Lat1 float, @Long1 float, @Lat2 float, @Long2 float)
RETURNS float
AS
BEGIN
-- Declare the return variable here
DECLARE @Result float
DECLARE @LatDiff float, @LongDiff float
SELECT @LatDiff = @Lat1 - @Lat2
SELECT @LongDiff = @Long1 - @Long2
SELECT @Result = (@LatDiff * @LatDiff) + (@LongDiff * @LongDiff)
-- Return the result of the function
RETURN @Result
END
我在这里错过了什么吗?
在 SQL Server 中使用 UDF 是否应该比向 .Net 提供比所需的多 25% 的记录要快得多,还有 DataReader 的开销、进程之间的通信等等?
我在那个 UDF 中做错了什么导致它运行缓慢?
有什么办法可以改善吗?
非常感谢你!