在一次将较少的记录加载到php数组时,性能会大幅提升

时间:2016-03-02 21:04:45

标签: php sql cron

我有一个占用太多内存的cron作业(我后来发现它在我的服务器上达到了php超时)。我决定尝试通过重构代码来加载少量要操作的数据来修复它。假设Record是负责与数据库表'Record'连接的类,原始代码看起来类似于:

$allRecords = Record::getAll();                // $records contains Record instances from every record in the db, > 100k array elements

do{
    $records = array_splice($allRecords, 500);
    foreach($records as $record){
        $record->doStuff();                    // modify some data and save it back to the database
    }
}while(!empty($allRecords))

现在代码看起来像这样:

$ids = Record::getAllIDs();           // $ids is an array of ints which are the id numbers for every record in the database

do{
    $records = [];
    foreach($ids as $key => $id){
        $records[] = new Record($id); // add single Record instance to working pool
        unset($id[$key]);             // remove id so we don't do same thing twice
        if(sizeof($records)===500)    // only want 500 at a time to save on memory
            break;
    }
    foreach($records as $record){
        $record->doStuff();           // same as before
    }

}while(!empty($ids))

显然,这会占用更少的系统内存,因为我首先想要做的就是这样做。令我困惑的是,这最终会占用相当少的时间。我经常看到这个cron需要一个多小时才能完成,现在需要15到20分钟才能运行相同数量的记录。任何人都有任何想法,为什么会出现这种情况?最后,我仍然从数据库中加载相同数量的记录,我认为将其分解会使其变慢,而不是更快。

1 个答案:

答案 0 :(得分:1)

我的猜测是在磁盘上进行大量交换。

话虽如此,我认为你在循环中没有实际的好处 如果你删除它们,它应该表现得更好。

# as per your example try to run it like this
$ids = Record::getAllIDs();           // $ids is an array of ints which are the id numbers for every record in the database

foreach($ids as $key => $id){
    new Record($id)->doStuff(); // add single Record instance to working pool
}