应用程序如何执行邻近搜索?例如,用户键入邮政编码,然后应用程序列出距离接近的20英里范围内的所有商家。
我想在PHP和MySQL中构建类似的东西。这种方法是否正确?
这样好吗?在第3步中,我将计算每个查询的接近度。最好是有一个PROXIMITY表,列出每个企业和几个参考位置之间的距离吗?
答案 0 :(得分:11)
我们用它来做数千点。如果您在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
答案 1 :(得分:9)
如果有足够的记录速度,那么这是一种提前索引它们的方法。
定义一侧约20英里的垃圾箱网格。将箱号存储在每个商店的记录中。在搜索时,计算与搜索点相距20英里半径的所有箱的数量。然后检索任何这些箱中的所有商店,并像以前一样继续。
答案 2 :(得分:2)
我们为大约1200个地点执行此操作。我会动态使用Haversine公式,虽然取决于你的应用程序,最好将它存储在PHP而不是SQL中。 (我们的实施是在.net,所以你的milage可能会有所不同)。
我们实施它的方式真的是我们最大的缺点是,每次计算(直到最近)都必须在数据层上计算得很慢(当我说慢时,我的意思是非瞬时它需要一个第二个左右),但这是因为它必须根据提供的邮政编码计算所有1200个地点的距离。
根据您选择的路线,有多种方法可以加快数字距离计算,方法是查看经度和纬度并移除预定义范围之外的数据(例如,如果您查看20英里范围内的所有地址)有一个经度范围,你可以计算出所有地址必须落在20英里以外。)如果需要,这可以加快你的查询速度。
我们实际上已经考虑过在数据库中存储所有可能的组合。实际上,它听起来像是一个大型数据存储,但实际上并不是在大范围内。使用索引它可以非常快,而且你不必担心算法优化等。我们决定反对它,因为我们在C#中有等式,它允许我们缓存所有计算所需的信息。业务层。要么工作得很好,这只是你的偏好的问题。