计算大型数据集的地理点之间的距离



我正在构建一个在线Symfony应用程序,作为开发过程的一部分,我的任务是根据与登录用户的距离对一定数量的数据库记录进行排序;该用户可以随意扩大搜索半径,达到整个世界的大小。

在任何时候,我都可以访问登录用户的GPS坐标,并在数据库表上保存了各个兴趣点的纬度和经度。

目前,POI 表中只有 400 条记录,但由于每次访问时都必须提取数据量,查询时间已经略多于一秒。向此类工作负载添加 400 个三角函数将很快使此类执行时间超出可接受性。

因此,我需要一种既快速又准确的方法来计算这样的距离;

我已经阅读了多篇建议使用Haversine公式的文章,但我发现对于我的需求来说太慢了,即使是像这样的广泛文章也没有任何帮助;

考虑到我很快就会到达成千上万的 POI,同时记录来自世界各地的数千名用户,我该如何处理(并希望解决(这样的问题?

我正在使用PHP 7.0,Symfony 3.2和Doctrine; pdo 连接到 Mysql 服务器,使用 innoDB 作为数据库引擎
我的客户重视准确性而不是速度,但无法忍受等待超过 5 秒
查询结果是分页的,因此不可能将排序委托给客户端
数据库和 php 服务器共享相同的(可怕的(资源池, 并且此类池将与其他应用程序共享

附带说明一下,某些 POI 可能会在特定日期后过期

你让我添加它,所以我会。

您确定性能打击来自Haversine吗? 我们已经在我的工作中成功地在生产中使用了这个公式的 PHP 实现大约 2 年,并且我们进行了大量搜索(高峰时段每分钟约 150k(。

我无法详细介绍我的工作,但我可以说我们使用狮身人面像,mongoDB,mysql和RabbitMq的组合。

无论如何,狮身人面像和 mysql 都遭受距离计算实施不佳的问题,在 100 英里的距离上损失了大约 2 英里的精度。(这就是我们使用它的原因(

您可以做的一件事是对运行Haversine公式所需的时间进行基准测试,当您遇到性能问题时,良好的基准测试是第一步。

虽然我不是交响乐用户,但我确实有一个专门为这件事制作的课程。 这是我在业余时间构建的更大框架(进化(的一部分。你可以在这里上课

https://github.com/ArtisticPhoenix/Evo/blob/master/Evo/Benchmark.php

使用起来非常简单

$mark = Benchmark::getInstance()->mark();
... code to time ...
echo Benchmark::getInstance()->format($mark);

并将输出类似的东西

10 milliseconds
5 minutes 3 milliseconds
ect..

它的设计使您可以使用多种marks

$mark = Benchmark::getInstance()->mark();
... code to time ...
$mark1 = Benchmark::getInstance()->mark();
... more code to time ...
echo "TotalTime: ".Benchmark::getInstance()->format($mark);
echo "MethodTime: ".Benchmark::getInstance()->format($mark1);
etc..

它基本上只记录microtime(true)当你调用mark()并返回一个标识符$mark然后如果你用标识符调用mark($mark),它将从当前microtime(true)中减去它。 调用format($mark)只是使它更具"人类"的可读性。

希望对您有所帮助!

相关内容

  • 没有找到相关文章

最新更新