while循环中的php性能问题
我使用PHP来执行纬度/经度点以生成JS并在OSM Map上显示点。 当我在录音中暂停10分钟或更长时间时,我想在地图上制作一首新曲目。
我目前的数据集大约有10万个不同轨道上的30000条记录(有些轨道大约有300个点,其他轨道有数千个)。
我遇到了PHP的性能问题。 当环路聚集数百个点时,数据处理速度很快,但如果轨道有数千个点,则性能急剧下降。
这是每个曲目继续每个点所需的时间
+-----------------+------------------------------+
| Points On Track | Time To Proceed 10000 Points |
+-----------------+------------------------------+
| 21 | 0.75 |
| 18865 | 14.52 |
| 539 | 0.79 |
| 395 | 0.71 |
| 827 | 0.79 |
| 400 | 0.74 |
| 674 | 0.78 |
| 2060 | 1.01 |
| 2056 | 0.99 |
| 477 | 0.73 |
| 628 | 0.77 |
| 472 | 0.73 |
+-----------------+------------------------------+
我们可以看到,当我在一条赛道上有很多积分时,表演会戏剧性地下降。 在这种特殊情况下,处理所有点需要大约30次。 如果我将每首曲目的点数限制在500分以下,表演效果会非常好(约需2.5秒才能完成我的数据集)。
我使用Synology DS415play作为网络服务器。
这是我的代码:
$dataTab = array();
if ($result = $mysqli->query($sql))
{
$count = 0;
$row = $result->fetch_array();
$data = $dataTab[$tabPrt] . "[" . $row['latitude'] . "," . $row['longitude'] . "]," ;
$date = new DateTime($row['time']);
while($row = $result->fetch_array())
{
$count++;
$newDate = new DateTime($row['time']);
if(($newDate->getTimestamp() - $date->getTimestamp()) > 600)
{
array_push($dataTab, $data);
$data= "";
$count = 0;
}
$data = $data . "[" . $row['latitude'] . "," . $row['longitude'] . "]," ;
$date = $newDate;
}
array_push($dataTab, $data);
}
如果我将每个音轨限制在500点以下,那么性能表现相当不错
$dataTab = array();
if ($result = $mysqli->query($sql))
{
$count = 0;
$row = $result->fetch_array();
$data = $dataTab[$tabPrt] . "[" . $row['latitude'] . "," . $row['longitude'] . "]," ;
$date = new DateTime($row['time']);
while($row = $result->fetch_array())
{
$count++;
$newDate = new DateTime($row['time']);
if(($newDate->getTimestamp() - $date->getTimestamp()) > 600
|| $count > 500)
{
array_push($dataTab, $data);
$data= "";
$count = 0;
}
$data = $data . "[" . $row['latitude'] . "," . $row['longitude'] . "]," ;
$date = $newDate;
}
array_push($dataTab, $data);
}
谢谢
编辑:我在这里提供了一个数据样本:http://109.190.92.126/tracker/gpsData.sql慢速脚本:http://109.190.92.126/tracker/map.php正常执行速度通过分割每个轨道(最多500点):http://109.190.92.126/tracker/map_split.php
谢谢
这是最终产品(它在Heroku上,所以请等到dyno启动)http://sove.herokuapp.com/gps/
解决方案背后的想法是计算服务器端的时间戳差异,并处理数组中的数据。
脚本在我的MBP中以0.278秒结束,占用15.75MB内存, $ts
最终输出是一组路由(总共有7个)。
有很多优化,包括跳过相同的坐标点。 缩放边界在地图上不正确,但你会知道。 我应该真的问过这份工作的赏金...如果你喜欢这个结果,那么让我知道,我可以分享代码库。
来源:https://gist.github.com/jpaljasma/04f54e0d2fa3a632071e
如果在最坏的情况下从数据库中获得18000条记录,则可以将时间戳检查移动到查询中以显着降低它,看起来您正在做的所有操作都是看看是否有10分钟的间隔,然后再推送到一个数组可以在mysql级别完成,这样你就不会每次从数据库中获取18000行,只需要你需要的那一行。
如果你发布你的mysql查询,我们可以看看把它放在那里。
编辑:尝试将查询更改为此:
SELECT time, latitude, longitude
FROM gpsData
WHERE time >= '2015-09-01'
AND provider = 'gps'
ORDER BY time DESC
链接地址: http://www.djcxy.com/p/29939.html
上一篇: php performance issue in while loop
下一篇: Assigning a value to a constant syntax or semantic error?