好。所以我一直在拉着我的头发试图找出为什么我的脚本永远运行。我已经确定了一个潜在的原因,并希望找到一种更有效的方式来执行以下功能:
function getwrs($obj, $recs) {
foreach ($obj as $key => $val) {
for ($i=0; $i<count($recs); $i++) {
$wr = array();
if ($recs[$i][0] === $key) {
$wr = $recs[$i];
break;
}
}
if (count($wr) > 0) {
for ($i=0; $i<count($val); $i++) {
if ($val[$i]["time"] < $wr[1] && abs($wr[1] - $val[$i]["time"]) < 30) {
$uwrs[] = array($val[$i], $wr);
}
}
}
}
return $uwrs;
}
我正在调用此函数:
$wrs = getwrs($top15["pro"], $recs);
其中$top15["pro"]
是具有以下结构的多维数组:
[MAP1NAME] => Array
(
[0] => Array
(
[authid] => XXXX
[name] => XXXX
[time] => XXXX
[date] => XXXX
...
)
)
[MAP2NAME] => Array
(
[0] => Array
(
[authid] => XXXX
[name] => XXXX
[time] => XXXX
[date] => XXXX
...
)
[1] => Array
(
[authid] => XXXX
[name] => XXXX
[time] => XXXX
[date] => XXXX
...
)
...
)
并且包含超过1500个条目,$ recs是包含可比较值的数组和具有以下结构的约3000个条目:
[0] => Array
(
[0] => MAP1NAME
[1] => TIMEVAL
[2] => USERNAME1
[3] => COUNTRY
)
...
此功能的目的是通过将数据库中每个地图的时间值($top15
)与官方世界记录数组($recs
)中的时间值进行比较来查找非官方世界记录。
现在我从我的数据库中获取每个地图名称,并从官方世界记录数组中找到相同的字符串,然后如果有正式记录,则将地图的官方世界记录值存储在变量$wr
中。接下来,我遍历我的数据库中已完成时间的数组,以查找哪些(如果有的话)小于官方记录时间。每次都是这样,我将有关我的数据库时间和正式记录时间(用户,时间等)的信息推送到新阵列。对于我的数据库中的每个键(映射名称)重复此操作。最后,该函数返回我的非官方世界记录数组($uwrs
)。
问题很简单:出于某种原因,这需要太长时间。我最初用JavaScript编写了我的脚本并且响应很快,所以我可能会认为我在这里做错了。有什么帮助吗?
编辑:我已经使用xdebug来查明问题,当我添加对此函数的调用时,我的输出文件从3MB变为超过30MB,脚本运行时间从大约1秒到15-20秒。我对这个工具比较陌生,所以我不知道这些信息是否重要。
编辑2:根据请求,我的数据库结构如下:
map | authid | name | time | date | weapon
例如:
kzbr_brickngrasshop | STEAM_0:1:XXXXXXX | John Travolta kz-endo | 23.582824 | 2013-08-25 | 03:40:17 | knife
答案 0 :(得分:1)
在多次阅读您的问题后,我假设您需要一种方法来比较来自两个不同表格的数据。
出于演示目的和简洁性,假设您有两个表official
和unofficial
。
official
和unofficial
表共享相同的结构 -
------------+-------------+----------+----------+-----------
mapid | authid | name | time | date
------------+-------------+----------+----------+-----------
map1name | 1 | bob | 03:40:17 | 2013-08-25
------------+-------------+----------+----------+-----------
map2name | 2 | hop | 01:10:56 | 2012-04-12
------------+-------------+----------+----------+-----------
map3name | 3 | cherry | 11:08:14 | 2013-05-14
------------+-------------+----------+----------+-----------
map4name | 4 | adam | 09:16:43 | 2013-07-10
------------+-------------+----------+----------+-----------
map5name | 5 | zyl | 06:01:53 | 2012-09-30
------------+-------------+----------+----------+-----------
现在你可以做的是执行一些高级的mysqlqueries来从两个表中查找数据。
SELECT * FROM `unofficial` JOIN `official` WHERE `official.mapid` = `unofficial.mapid` AND TIME_TO_SEC(`official.time`) > TIME_TO_SEC(`unofficial.time`) AND ABS( TIME_TO_SEC(`official.time`) - TIME_TO_SEC(`unofficial.time`) ) < 1800
这里做了什么:
这里我们执行了一个mysql查询,在执行三个条件后连接表和获取结果 -
(i)他们的地图ID必须相同。根据您上面的代码,我认为您希望匹配两个表中的地图ID,以便找到非官方的世界记录。
(ii)unofficial
表的时间必须小于official
表的时间。我再次从你上面的代码中假设它。 TIME_TO_SEC
是mysql
函数,可将时间转换为秒。与TIME_TO_SEC('01:01:06')一样,返回3666。
(iii)第三是时间差小于30秒。再次在你的代码中。
我的查询可能有一些错误,如拼写错误或选择错误的列等,因为我没有针对真实数据库进行测试。但这个想法几乎是一样的。您可以搜索相应的查询或阅读文档。
我希望这会对你有帮助。
答案 1 :(得分:0)
通过创建13,000,000个不同的变量并在执行循环之前将它们设置为每个数组的长度来解决问题。阅读透露,我数到1500/3000 /等。每次我使用for循环。猜猜它会影响PHP的性能..