Оптимизация foreach для тысяч предметов

Я запускаю код ниже по набору из 25 000 результатов. Мне нужно оптимизировать его, потому что я нажимаю ограничение памяти.

$oldproducts = Oldproduct::model()->findAll(); /*(here i have 25,000 results)*/ foreach($oldproducts as $oldproduct) : $criteria = new CDbCriteria; $criteria->compare('`someid`', $oldproduct->someid); $finds = Newproduct::model()->findAll($criteria); if (empty($finds)) { $new = new Newproduct; $new->someid = $oldproduct->someid; $new->save(); } else { foreach($finds as $find) : if ($find->price != $oldproduct->price) { $find->attributes=array('price' => $oldproduct->price); $find->save(); } endforeach; } endforeach; 

Код сравнивает строки из двух таблиц на someid . Если он находит совпадение, он обновляет столбец цены , если не создает новую запись.

Используйте CDataProviderIterator который:

… позволяет выполнять итерацию по большим наборам данных без сохранения всего набора в памяти.

Сначала вам нужно передать экземпляр CDataProvider :

 $dataProvider = new CActiveDataProvider("Oldproduct"); $iterator = new CDataProviderIterator($dataProvider); foreach($iterator as $item) { // do stuff } 

Вы можете обрабатывать строки в кусках ~ 5000 вместо того, чтобы получать все строки за 1 проход!

 $cnt = 5000; $offset = 0; do { $oldproducts = Oldproduct::model()->limit($cnt)->offset($offset)->findAll(); /*(here i have 25,000 results)*/ foreach($oldproducts as $oldproduct) { // your code } $offset += $cnt; } while($oldproducts >= $cnt);