Magento:更新产品属性的最快方法


15

我正在寻找质量属性更新的最快,最可靠的方法。下面是我知道的方法,但是我不知道应该使用哪种方法。

$store_id = 0;
Mage::getSingleton('catalog/product_action')->updateAttributes(
    array($product_id),
    array('attribute_code' => $attribute_code),
    $store_id
);

要么

$product->setData($attribute_code, 1234); 
$product->getResource()->saveAttribute($product, $attribute_code); 

Answers:


31

最快的方法是直接选择和插入/更新数据库,但这不是最安全的方法。您可以轻松破坏东西。

我使用这种Mage::getSingleton('catalog/product_action')->updateAttributes(...)方法。
它的速度很快,您可以用它来批量更新产品属性,也可以更新特定商店的属性值。
我认为它涵盖了大多数情况。


谢谢marius,我期待您的回应,顺便说一句,您的最终模块创建者是kool
Deepak Mallah 2014年

1
这实际上不是最快的选择...请在下面检查我的答案
Fra十二月

@Fra您的方法如何更快?它涉及load。除了快速以外,什么都没有。例如,在方法2中,带有产品负载的第一行是无用的。您不在$product任何地方使用。
马吕斯

@Fra。当您拒绝某人的回答时,说出原因是一件好事。我的答案怎么了?
马里斯(Marius)

1
我可以为您的回答说同样的话...这不是最快的方法。直接SQL查询是最快的方法。我认为您的理由不足以拒绝投票。但是您有权发表自己的意见。
马吕斯

27

实际上,有3种方法可以在不保存完整产品的情况下更新产品上的属性。根据代码/要求,一个可能比另一个更快。

方法1:

$product = Mage::getModel('catalog/product')->load($product_id);
$resource = $product->getResource();

$product->setData($attribue_code, $value);
$resource->saveAttribute($product, $attribute_code);

方法2:

$updater = Mage::getSingleton('catalog/product_action');
$updater->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

方法3 :(最快)

 $update_resource = Mage::getResourceSingleton('catalog/product_action');
 $update_resource->updateAttributes(array($product_id), array( $attribute_code => $value), 0);

以上所有方法都可以更快地保存整个产品,但是仍然存在一些主要的性能差异:

Method 1

  • 是最快的,但需要您加载产品。
  • 它不会触发reindex事件(这就是为什么更快)
  • 它在前端工作

Method 2

  • 允许批量更新产品
    (您可以传递多个产品和多个属性)
  • 它触发群众行动事件和相对依赖的重新索引
  • 它在前端不起作用

Method 3

  • 它类似于方法2,但不调用任何其他观察者/索引器
    (因此,它是方法1和2之间的混合方法)

无论如何,方法3都是更灵活的一种,您必须手动为这些产品/属性重新编制索引。(为了使它们在前端更新)
,如果您想快速更新很多产品,然后在最后调用重新索引,则可能会很有用。
(如果您使用方法2,则在更新后将为每个产品调用一个重新索引,而这些多次调用会使整个过程变慢)

要手动为单个产品重新编制索引,请参阅Mage_Catalog_Model_Product_Flat_Indexer提供的功能,例如:

  • updateAttribute($attributeCode, $store = null, $productIds = null)
  • updateProduct($productIds, $store = null)
  • ...

4
这将是总是更好的评论downvote ...
法兰克福机场

请注意,$ value应该是一个值代码(整数),而不是您在界面中看到的“文本”值
Ali Alwash

嗯,有趣。方法2听起来很棒,只有您无法控制“反馈”,什么成功了,什么没成功?方法1也不错。但是,当我完成对数据的循环更新后,是否可以手动启动重新索引,也许可以解决特定产品ID的问题?
snh_nl

奇怪。使用方法2。我通过列```收到错误未知过滤器捕获的异常:SQLSTATE [42S22]:找不到列:1054'字段列表'中的未知列'catalog_product_entity.value_id',查询是:SELECT catalog_product_entityvalue_idcatalog_product_entity哪里(entity_type_id = 4 AND attribute_id = '68'AND entity_id = '29')```没想到。运行于1.9.3.2
snh_nl

1
节省了我几个小时的工作。
dipole_moment

3

更新资料

我正在寻找质量属性更新的最快,最可靠的方法

属性或产品的“质量属性更新”?

认为已经回答了更新多个属性的问题,但是对于产品这可能是有用的...

如果要更新收藏中的产品,则不应执行此操作...

foreach ($collection as $product) {
    $product->setSomeData(...);
    # not here
    $product->save();
}

这将调度事件,重建价格规则和指数。有了这个,没有事件(和其他一些事情)被跳过,并且速度更快。

foreach ($collection as $product) {
    $product->setSomeData(...);
}
$collection->save();

为避免价格规则更新,您可以添加...

$product->setIsMassupdate(true);

要即时禁用/启用重新索引,请看一下... https://github.com/Flagbit/Magento-ChangeAttributeSet/commit/676f3af77fec880bc64333403675d183e8639fae

/**
 * Set indexer modes to manual
 */
private function _storeRealtimeIndexer()
{
    $collection = Mage::getSingleton('index/indexer')->getProcessesCollection();
    foreach ($collection as $process) {
        if($process->getMode() != Mage_Index_Model_Process::MODE_MANUAL){
            $this->_index[] = $process->getIndexerCode();
            $process->setData('mode', Mage_Index_Model_Process::MODE_MANUAL)->save();
        }
    }

}
/**
 * Restore indexer modes to realtime an reindex product data
 */
private function _restoreRealtimeIndexer()
{
    $reindexCodes = array(
        'catalog_product_attribute',
        'catalog_product_flat'
    );
    $indexer = Mage::getSingleton('index/indexer');
    foreach ($this->_index as $code) {
        $process = $indexer->getProcessByCode($code);
        if (in_array($code, $reindexCodes)) {
            $process->reindexAll();
        }
        $process->setData('mode', Mage_Index_Model_Process::MODE_REAL_TIME)->save();
    }
}

而且在批量(产品)更新之前刷新缓存可以提高性能……

Mage::app()->getCacheInstance()->flush();

从此处进行调试的一些数字:https//github.com/Flagbit/Magento-ChangeAttributeSet/issues/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) 似乎不是最快的方法...至少在mutlistore设置和平面表打开的情况下不是...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • 总含税 墙时间(微秒):437,787微秒
    • 总含税 CPU(微秒):423,600微秒
    • 总含税 MemUse(字节):4,433,848字节
    • 总含税 PeakMemUse(字节):4,395,128字节
    • 函数调用数:25,711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • 总含税 墙时间(微秒):3,676,950微秒
    • 总含税 CPU(微秒):3,122,064微秒
    • 总含税 MemUse(字节):8,174,792字节
    • 总含税 PeakMemUse(字节):8,199,192字节
    • 函数调用数:150,132
  • updateAttributes() (资源单例)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • 总含税 墙壁时间(微秒):94,155微秒
    • 总含税 CPU(微秒):48,568微秒
    • 总含税 MemUse(字节):1,426,304字节
    • 总含税 PeakMemUse(字节):1,370,456字节
    • 函数调用数:2,221

您可以查看我的答案以了解为什么这些功能需要不同的时间...
Fra Fra

对于下拉数据,是否updateAttributes() (resource singleton)需要实际的管理员值?或下拉元素的ID?(以某种方式,我们总是使用此方法没有值/空值,即未选择任何内容
snh_nl

@snh_nl,您必须使用ID-对于多选属性,逗号分隔。
sv3n
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.