使用纬度 - 经度 - 邮政编码数据库选择3个最近的位置

时间:2011-03-04 14:56:11

标签: php mysql performance latitude-longitude

我的脚本存在一些性能问题,所以我想知道是否有人知道更好的方法来解决这个问题。

我有一个包含位置及其邮政编码(id,名称,邮政编码)的数据库。在另一个表中,我有与邮政编码相关的纬度和经度(纬度,长度,邮政编码)。该脚本要求用户提供邮政编码并返回3个最近的位置。

我目前正在这样做的方式是:我从db到本地数组的所有位置,然后使用mysql查询我在每个位置的位置和用户的邮政编码之间获得距离。

SELECT SQRT( POW( (
    uc1.lat - uc2.lat
    ), 2 ) + POW( (
    uc1.long - uc2.long
    ), 2 ) ) 
FROM postcodes uc1
LEFT JOIN postcodes uc2 ON uc1.postcode = "$postcode1"
WHERE uc2.code = "$psotcode2"

之后我对数组进行排序并显示前3个元素。

如果位置数量很少,这样可以正常工作,但随着它们接近数千个性能成为一个问题。

有什么想法吗?

编辑: 我非常清楚地球的曲率。我发布了这个查询而不是更重要的数据,因此更容易理解实际发生的事情

2 个答案:

答案 0 :(得分:1)

创建一个“边界框”以在SQL查询的WHERE子句中使用,如in this article on Movable Type所述(使用PHP代码示例),然后在查询中包含Haversine公式以计算实际距离,并订购距离ASC的结果。

这是帮助您提高性能的边界框,因为这意味着您只需对数据的一小部分进行昂贵的距离计算

答案 1 :(得分:0)

首先,距离计算不考虑地球的曲率

你应该看看使用类似的东西

SELECT id, place_name,
((ACOS(SIN($lat * PI() / 180) * SIN(`lat` * PI() / 180) + COS($lat * PI() / 180) * COS(`lat` * PI() / 180) * COS(($lon – `lon`) * PI() / 180)) * 180 / PI()) * 60 * 1.1515) AS distance
FROM places
ORDER BY distance ASC