Magento: Самый быстрый способ обновить атрибут продукта


Я ищу самый быстрый и надежный метод массового обновления атрибутов. Ниже приведены методы, о которых я знаю, но я не знаю, с которыми мне следует пойти.

$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); 
Author: Rafael Corrêa Gomes, 2014-05-21

3 answers

Самый быстрый способ - выполнить прямой выбор и вставки/обновления в базе данных, но это не самый безопасный способ. Вы можете легко сломать вещи.

Я использую подход Mage::getSingleton('catalog/product_action')->updateAttributes(...).
Это быстро, вы можете использовать его для массового обновления атрибутов продукта, вы можете обновить значение атрибута для конкретного магазина.
Я думаю, что это охватывает большинство необходимых случаев.

 33
Author: Marius, 2014-05-21 06:18:29

На самом деле есть 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:

  • является самым быстрым, но требуется, чтобы вы загрузили продукт.
  • это не вызывает событие переиндексации (поэтому быстрее)
  • он работает в интерфейсе

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)
  • ...
 29
Author: Fra, 2019-11-15 09:43:23

Обновление

Я ищу самый быстрый и надежный метод массового обновления атрибутов

"Массовое обновление атрибутов" для атрибутов или продуктов?

Думаю, что обновление нескольких атрибутов уже получено, но для продуктов это может быть полезно...

Если вы хотите обновить продукты из коллекции, вам не следует этого делать...

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 микросекунд
    • Всего Вкл. Процессор (микросекунды): 423 600 микросекунд
    • Всего Вкл. Объем памяти (байт): 4 433 848 байт
    • Всего Вкл. Пиковое значение (байт): 4,395,128 байты
    • Количество вызовов функций: 25 711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    
    • Всего Вкл. Время на стене (микросекунда): 3,676,950 микросекунд
    • Всего Вкл. Процессор (микросекунды): 3,122,064 микросекунды
    • Всего Вкл. Объем памяти (байт): 8 174 792 байта
    • Всего Вкл. Пиковое значение (байт): 8,199,192 байта
    • Количество вызовов функций: 150 132
  • updateAttributes() (одноэлементный ресурс)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    
    • Всего Вкл. Время на стене (микросекунда): 94 155 микросекунд
    • Всего Вкл. Процессор (микросекунды): 48 568 микросекунд
    • Всего Вкл. Объем памяти (байт): 1 426 304 байта
    • Всего Вкл. Пиковое значение (байт): 1 370 456 байт
    • Количество вызовов функций: 2221
 3
Author: sv3n, 2017-10-24 18:28:25