长时间运行的控制台命令会变慢

时间:2016-11-29 00:12:18

标签: php mysql regex laravel

初始文字

我在Laravel项目中创建了控制台。该命令从一个表中获取html数据,通过preg_match检查每个记录的两个模式匹配。如果它返回true,则正在对其他表的记录进行更新,该记录具有与foreach循环中当前焦点的第一个表中的记录相同的属性。 记录数量为cca 3500

在cca 150迭代之后,命令急剧减慢,我需要一天才能完成命令。

我从这个论坛上阅读了所有类似的问题,但他们并没有帮助我。甚至没有关于强制垃圾收集的答案。

代码如下:

$ras = RecordsA::all();
$pattern = '/===this is the pattern===/';
foreach($ras as $ra){
    $html = $ra->html;
    $rb = RecordB::where("url", $ra->url)->first();
    $rb->phone = preg_match($pattern, $html, $matches) ? $matches[1] : $rb->phone;
    $rb->save();
}

我正在搜索有关 preg_match 性能的可能问题,但未成功。

有没有人遇到过这样的问题?

对于MMMTroy更新

我忘了说我也尝试过自定义但与您的代码类似:

$counter = DB::select("select count(*) as count from records_a")->first();
//Pattern for Wiktor Stribiżew :)
    $pattern = '/Telefon:([^<])+</';
for($i = 0; $i < $counter->count; $i+=150){
    $ras = RecordsA::limit(150)->offset($i);
    foreach($ras as $ra){
        $html = $ra->html;
        $rb = RecordB::where("url", $ra->url)->first();
        $rb->phone = preg_match($pattern, $html, $matches) ? $matches[1] : $rb->phone;
        $rb->save();
    }
}

3 个答案:

答案 0 :(得分:1)

“OFFSET的分页”是Order(N * N)。订购(N)会更好,所以“记住你离开的地方”。

More discussion

答案 1 :(得分:0)

你很有可能内存不足。 Laravel有一个方便的方法来“块”结果,通过限制你循环的项目数量大大减少了内存量。尝试这样的事情。

circle.yml

这样做的目的是一次抓取100条记录,然后循环遍历这些记录。完成后,它会创建一个偏移量并抓取数据库中的下一个记录。这将阻止整个循环存储在内存中。

答案 2 :(得分:0)

您的数据库在循环播放时是否会增长?如果找不到RecordB并返回null会怎样?感觉RecordB您的桌子正在增长,导致搜索查询速度变慢。

最近出现了类似的问题并达到内存限制。减少东西和泄漏记忆的数字1有1件事。 DB::$queryLog(禁用它:DB::disableQueryLog();)。每次调用查询时,查询字符串都将存储在变量中。

也许其中一个原因是导致它,但是代码看起来很好。