针对80k行的PHP数组优化

时间:2015-06-29 12:52:17

标签: php arrays

我需要帮助才能找到克服memory_limit的解决方法。我的限制是128MB,从数据库I获得大约80k行,脚本停在66k。谢谢你的帮助。

代码:

$posibilities = [];
    foreach ($result as $item) {
            $domainWord = str_replace("." . $item->tld, "", $item->address);

            for ($i = 0; $i + 2 < strlen($domainWord); $i++) {
                $tri = $domainWord[$i] . $domainWord[$i + 1] . $domainWord[$i + 2];


                if (array_key_exists($tri, $possibilities)) {
                    $possibilities[$tri] += 1;
                } else {
                    $possibilities[$tri] = 1;
                }
            }
        }

2 个答案:

答案 0 :(得分:3)

根据您的算法,您的瓶颈很可能不是数据库查询,而是您正在构建的$possibilities数组。

如果我正确读取您的代码,您将从数据库中获取域名列表。从每个域名中,首先删除顶级域名。

然后,您从结果字符串的左侧到右侧逐个字符地行走,并从该字符串中收集字符的三元组,如下所示:

example.com =&gt; ['exa', 'xam', 'amp', 'mpl', 'ple']

你将这些三元组存储在数组的keys中,这是个不错的主意,你也可以计算它们,这对内存消耗没有任何影响。但是,我的猜测是,26个字母和10个数字的可能三元组的数量是36 ^ 3 = 46656种可能性,每个只需3个字节,仅用于阵列内的,不知道如何围绕它的许多样板代码,从你的内存限制中获取了很多。

可能有人会告诉你PHP如何使用内存及其数据库游标,我不知道,但你可以做一个技巧来分析你的内存消耗。

将来电置于memory-get-usage

  • 每次迭代之前和之后,所以你就会知道每个游标进程浪费了多少内存,
  • 每次加入$possibilities之前和之后。

立即打印出来。因此,您将能够运行您的代码并实时查看您的记忆的内容和认真度。

此外,在每次迭代后尝试unset $item。它实际上可能有所帮助。

了解用于获取$result迭代器的特定数据库访问库将会有很大帮助。

答案 1 :(得分:0)

鉴于您提供的微小(相当无用)的代码片段,我想为您提供MySQL答案,但我不确定您是否正在使用MySQL?

但是 - 优化你的桌子。

  • 使用EXPLAIN优化您的查询。重写您的查询以在查询中而不是在PHP代码中放置尽可能多的逻辑。 编辑:如果你正在使用MySQL,那么在你的EXPLAIN关键字之前添加SELECT,结果将向你显示实际上你给MySQL的查询如何变成结果的解释。

  • 不要使用PHP strlen函数,因为这是内存效率低的 - 而是可以通过将字符串视为一组数组值进行比较,因此:

    for ($i = 0; !empty($domainWord[$i+2]); $i++) {

  • 你的MySQL中的
  • (如果那是你正在使用的那个)然后添加一个LIMIT子句,将查询分成3或4个块,比如每块25k行,可轻松适应66k行的最大工作容量。 Burki有这个好主意。

在每个块的末尾清理所有字符串并重新启动,设置为循环

$z = 0;
 while ($z < 4){
///do grab of data from database. Preserve only your output 
$z++;
}

但可能比其中任何一个更重要的是在你的问题中提供足够的细节! - 您想获得什么数据? - 你在存储什么数据? - 查找数据的标准是什么?

这些答案将帮助那些比我更了解的人向您展示如何正确优化您的数据库。