按 Postal/Zip 代码查找产品 |半正弦算法 |表现
Product Lookup By Postal/Zip Code | Haversine Algorithm | Performance
我有一个根据邮政编码搜索项目的应用程序。
在搜索邮政编码时,我 return 来自 City/Neighborhood 的所有产品(通过解析 postal/zip 代码完成)。
我现在需要根据与原始 postal/zip 代码的距离对这些产品进行排序。
我将 Lat/Long 存储在数据库中,并计划使用 Haversine 公式计算与原始查询的近似距离。
我的问题是,这个应该在哪里计算。
在 return 处理我的数据集之前,我应该在存储过程中执行此操作吗?
或者我应该 return 我的数据集,我的 Lat/Long,并在 return 发送给用户之前在服务器端计算它。
可能需要对最多 1000 个结果执行计算。
通常,数据库服务器是 IO 绑定的而不是 CPU 绑定的。 YMMV,但如果您的情况很典型,则最好在数据库服务器上执行 Haversine 计算。
我建议使用自定义查找 table 进行 反正弦 计算,因为您可以提供对数尺度的近似距离,例如:
100米,
300米,
1公里,
3公里,
10公里,
30公里,
> 30公里
然后使用线性插值作为细化。
对于单个大都市区遇到的典型距离,您可以考虑仅使用 the Taylor expansion for sin and cos 的 2 或 3 项而不是更精确的计算:
- sin(x) =~ x - x^3 / 6 + x^5 / 120
- cos(x) =~ 1 - x^2 / 2 + x^4 / 24
还记得对于收敛的泰勒级数,第 n 项之后的误差严格小于第 (n+1) 项的大小。这使您可以在达到所需精度后有效地终止计算,由于地球不是均匀球体,因此对于 Haversine 公式来说通常精度仅为 0.5%。
您使用的是 SQL Server 2008 或更高版本吗?如果是这样,我建议使用内置的地理数据类型,而不是直接进行 Haversine 计算。您可以有一个 table 的邮政编码,其中包含邮政编码(例如 90210)以及邮政编码的中心点或另一列中邮政编码覆盖的整个区域(或者如果这对你的申请)。然后,您可以使用 STDistance()
函数计算距离。此外,通过空间索引,您可以轻松获得按距离排序的列表。
我有一个根据邮政编码搜索项目的应用程序。
在搜索邮政编码时,我 return 来自 City/Neighborhood 的所有产品(通过解析 postal/zip 代码完成)。
我现在需要根据与原始 postal/zip 代码的距离对这些产品进行排序。
我将 Lat/Long 存储在数据库中,并计划使用 Haversine 公式计算与原始查询的近似距离。
我的问题是,这个应该在哪里计算。 在 return 处理我的数据集之前,我应该在存储过程中执行此操作吗?
或者我应该 return 我的数据集,我的 Lat/Long,并在 return 发送给用户之前在服务器端计算它。
可能需要对最多 1000 个结果执行计算。
通常,数据库服务器是 IO 绑定的而不是 CPU 绑定的。 YMMV,但如果您的情况很典型,则最好在数据库服务器上执行 Haversine 计算。
我建议使用自定义查找 table 进行 反正弦 计算,因为您可以提供对数尺度的近似距离,例如:
100米,
300米,
1公里,
3公里,
10公里,
30公里,
> 30公里
然后使用线性插值作为细化。
对于单个大都市区遇到的典型距离,您可以考虑仅使用 the Taylor expansion for sin and cos 的 2 或 3 项而不是更精确的计算:
- sin(x) =~ x - x^3 / 6 + x^5 / 120
- cos(x) =~ 1 - x^2 / 2 + x^4 / 24
还记得对于收敛的泰勒级数,第 n 项之后的误差严格小于第 (n+1) 项的大小。这使您可以在达到所需精度后有效地终止计算,由于地球不是均匀球体,因此对于 Haversine 公式来说通常精度仅为 0.5%。
您使用的是 SQL Server 2008 或更高版本吗?如果是这样,我建议使用内置的地理数据类型,而不是直接进行 Haversine 计算。您可以有一个 table 的邮政编码,其中包含邮政编码(例如 90210)以及邮政编码的中心点或另一列中邮政编码覆盖的整个区域(或者如果这对你的申请)。然后,您可以使用 STDistance()
函数计算距离。此外,通过空间索引,您可以轻松获得按距离排序的列表。