Я запускаю код ниже по набору из 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);