0

我在我的应用程序中使用 MySQL 来存储城市列表。每个 long/lat 代表城市的中心。

我希望能够将所有靠近特定城市的城市拉出 X 公里的距离。

我的问题是什么会为此目的更快地执行。

  • 使用点列,并使用“空间”查询来检索数据?

或者

  • 使用浮点经度列和浮点纬度列。然后在对这些值运行 SQL WHERE BETWEEN 查询之前,使用 java 代码生成距离之间的长/纬度。

我还有一个小问题,请求所有距离纽约 10 公里的城市是否有意义。当纽约的范围可能大于 10 公里?

4

2 回答 2

1

您可以使用Haversine 公式来查询数据库。

下面的查询是使用PDO

$stmt = $dbh->prepare("SELECT  name, lat, lng, ( 6371 * acos( cos( radians(?) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(?) ) + sin( radians(?) ) * sin( radians( lat ) ) ) ) AS distance FROM mytable HAVING distance < ? ORDER BY distance LIMIT 0 , 20");

// Assign parameters
$stmt->bindParam(1,$center_lat);
$stmt->bindParam(2,$center_lng);
$stmt->bindParam(3,$center_lat);
$stmt->bindParam(4,$radius);

在哪里

  1. 6371 是地球的半径,单位为 km
  2. $center_lat & $center_lng 位置坐标
  3. $center_lng 搜索半径

此查询在 457K 行的未索引数据库上运行需要 1.93 秒。

name Varchar(50) 
lat Decimal(9,6)
lng Decimal(9,6) 
于 2013-05-15T07:11:49.240 回答
1

在这种情况下,空间扩展总是会更好,因为它基于 R-Tree 索引,该索引针对 N 维空间中的范围搜索进行了优化。

而原生 mysql 索引是 B-Tree,在最好的情况下,只会使用索引中的一个字段(用于范围比较),或者根本不使用索引(如果您使用一些高级地理公式,如另一个答案)。

于 2013-05-16T00:03:53.883 回答