我在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 性能的可能问题,但未成功。
有没有人遇到过这样的问题?
我忘了说我也尝试过自定义但与您的代码类似:
$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();
}
}
答案 0 :(得分:1)
“OFFSET的分页”是Order(N * N)。订购(N)会更好,所以“记住你离开的地方”。
答案 1 :(得分:0)
你很有可能内存不足。 Laravel有一个方便的方法来“块”结果,通过限制你循环的项目数量大大减少了内存量。尝试这样的事情。
circle.yml
这样做的目的是一次抓取100条记录,然后循环遍历这些记录。完成后,它会创建一个偏移量并抓取数据库中的下一个记录。这将阻止整个循环存储在内存中。
答案 2 :(得分:0)
您的数据库在循环播放时是否会增长?如果找不到RecordB
并返回null
会怎样?感觉RecordB
您的桌子正在增长,导致搜索查询速度变慢。
最近出现了类似的问题并达到内存限制。减少东西和泄漏记忆的数字1有1件事。
DB::$queryLog
(禁用它:DB::disableQueryLog();
)。每次调用查询时,查询字符串都将存储在变量中。
也许其中一个原因是导致它,但是代码看起来很好。