Magento:更快地更新产品目录

时间:2011-11-17 12:39:05

标签: magento

我编写了很多脚本来根据某些或其他参数更新我的产品目录。在每个基础逻辑中都有类似的东西......

     //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();   
            }

虽然这项工作,但每次保存都是一个SQL更新查询,事实是拥有一个非常大的目录,这是相当慢的。

我想知道是否可以通过对产品进行单一保存而不是产品来加速。

1 个答案:

答案 0 :(得分:21)

编写速度更快的更新脚本可以做几件事。我不知道你是如何得到你的一些变量所以你需要修改以使它在你的情况下工作,但下面的代码应该比你目前的方式快得多。 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');