Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Magento: Updating Product Catalogs faster

Tags:

magento

I have written quite a few scripts to update my product catalog based on some or other parameter. In each of them the base logic is something simillar to this...

     //Get collection
     $collection = Mage::getModel('catalog/product')->getCollection();
     $collection->addAttributeToSelect('sku');
 $collection->addAttributeToSelect('publihser');
     $collection->addFieldToFilter(array(array('attribute'=>'publisher','eq'=>$publisher)));

     // for each product in collection do a individual save
     foreach ($collection as $product) {
    $product->setSKU($newValue);
    $product->save();   
            }

Though this work, each save is a SQL update query and the fact is that having a very large catalog, this is fairly slow.

I was wondering if this could be sped up by doing single save on the collection instead on the product.

like image 406
TheVyom Avatar asked Nov 17 '11 12:11

TheVyom


1 Answers

There are several things you can do to write a much faster update script. I don't know how you are getting some of your variables so you'll need to modify to get it working in your case, but the code below should be much faster than the way you are currently doing it. e.g:

// Set indexing to manual before starting updates, otherwise it'll continually get slower as you update
$processes = Mage::getSingleton('index/indexer')->getProcessesCollection();
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
$processes->walk('save');

// Get Collection
$collection = Mage::getModel('catalog/product')->getCollection()
    ->addAttributeToSelect('sku')
    ->addAttributeToSelect('publihser')
    ->addFieldToFilter(array(array('attribute'=>'publisher','eq'=>$publisher)));


function productUpdateCallback($args){
    $product = Mage::getModel('catalog/product');

    $product->setData($args['row']);

    $productId = $product->getId();

    $sku = 'yourSku';

    // Updates a single attribute, much faster than calling a full product save
    Mage::getSingleton('catalog/product_action')
        ->updateAttributes(array($productId), array('sku' => $sku), 0);
}

// Walk through collection, for large collections this is much faster than using foreach
Mage::getSingleton('core/resource_iterator')->walk($collection->getSelect(), array('productUpdateCallback'));


// Reindex all
$processes->walk('reindexAll');
// Set indexing back to realtime, if you have it set to manual normally you can comment this line out
$processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
$processes->walk('save');
like image 177
Jasuten Avatar answered Oct 01 '22 19:10

Jasuten