邻近搜索
应用程序如何执行邻近搜索?例如,用户键入邮政编码,然后应用程序按邻近度排序列出 20 英里内的所有商家。
我想在PHP和MySQL中构建类似的东西。这种方法是否正确?
- 获取我感兴趣的位置的地址并存储在我的数据库中
- 使用 Google 的地理编码服务对所有地址进行地理编码
- 编写包含 Haversine 公式的数据库查询以执行邻近搜索和排序
这样可以吗?在步骤 3 中,我将计算每个查询的邻近度。有一个列出每个企业和几个参考位置之间的距离的邻近性表是否更好?
应用程序如何执行邻近搜索?例如,用户键入邮政编码,然后应用程序按邻近度排序列出 20 英里内的所有商家。
我想在PHP和MySQL中构建类似的东西。这种方法是否正确?
这样可以吗?在步骤 3 中,我将计算每个查询的邻近度。有一个列出每个企业和几个参考位置之间的距离的邻近性表是否更好?
如果有足够的记录来衡量速度,这里有一种方法可以提前为它们编制索引。
定义一侧约 20 英里的条柱网格。将库位编号与每个商店的记录一起存储。在搜索时,计算与搜索点 20 英里半径相交的所有条柱的数量。然后检索任何这些条柱中的所有存储,并像以前一样继续。
我们用它来做几千个点。如果在 SQL 中执行此操作,则在“纬度和经度”列上设置索引非常重要。我们尝试在 SQL 2008 中使用空间索引执行此操作,但我们确实没有看到预期的性能提升。但是,如果要在距ZIP的一定距离内进行计算,则需要考虑是否要使用ZIP质心或邮政编码的多边形表示形式。
Haversine forumla是一个很好的起点。
我们没有遇到在飞行中计算距离的性能问题,对于某些应用程序,我们确实提前计算了它,在这些应用程序中,我们提前知道了点,并且会有数百万条记录。
SELECT
[DistanceRadius]=
69.09 *
DEGREES(
ACOS(
SIN( RADIANS(latitude) )*SIN( RADIANS(@ziplat) )
+
COS( RADIANS(latitude) )*COS( RADIANS(@ziplat) )
*
COS( RADIANS(longitude - (@ziplon)) )
)
)
,*
FROM
table
) sub
WHERE
sub.DistanceRadius < @radius