对所有 n 条记录使用诸如STDistance 之类的数据库函数是次优的。您的 CPU 开销将成倍增加。
您应该做的是检查您正在搜索的当前震中周围矩形内的点数。这是一个示例(在 MySQL 中):
SELECT * FROM `points`
WHERE `latitude` >= X1 AND `latitude` <= X2
AND `longitude` >= Y1 AND `longitude` <= Y2
这提供了减少的点,然后应该通过使用Haversine公式superset
计算正交距离(相对于地球的曲率)来进一步减少这些点。
不要忘记在和上设置复合索引。latitude
longitude
这是在PHP中:
<?php
function haversine($latitude1, $longitude1,
$latitude2, $longitude2, $unit = 'Mi') {
$theta = $longitude1 - $longitude2;
$distance = (sin(deg2rad($latitude1)) * sin(deg2rad($latitude2))) +
(cos(deg2rad($latitude1)) * cos(deg2rad($latitude2)) * cos(deg2rad($theta)));
$distance = acos($distance);
$distance = rad2deg($distance);
$distance = $distance * 60 * 1.1515;
switch ($unit) {
case 'Mi':
break;
case 'Km':
$distance = $distance * 1.609344;
}
return (round($distance, 2));
}
?>
回顾一下:
这是一个示例图像,说明了该怎么做:
第一次搜索将涉及边界框碰撞搜索(MySQL 示例)以确定superset
,不包括红点。第二个验证过程将涉及使用 Haversine 公式(PHP 示例)计算点是否在适当的正交距离内,并取 a subset
(由黑点组成)。