Magento: Schnellste Möglichkeit, ein Produktattribut zu aktualisieren


15

Ich suche nach der schnellsten und zuverlässigsten Methode zur Aktualisierung von Massenattributen. Unten sind die Methoden aufgeführt, die mir bekannt sind, aber ich weiß nicht, mit welchen ich gehen soll.

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

oder

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

Antworten:


31

Der schnellste Weg ist das direkte Auswählen und Einfügen / Aktualisieren in der Datenbank, aber das ist nicht der sicherste. Sie können leicht Sachen brechen.

Ich benutze den Mage::getSingleton('catalog/product_action')->updateAttributes(...)Ansatz.
Es ist schnell, Sie können es für die Massenaktualisierung von Produktattributen verwenden. Sie können einen Attributwert für ein bestimmtes Geschäft aktualisieren.
Ich denke, es deckt die meisten Fälle ab.


Dank marius ich war Ihre Antwort erwarten, btw Ihre ultimative Modul Schöpfer ist kool
Deepak Mallah

1
Es ist nicht wirklich die schnellste Wahl ... Überprüfen Sie meine Antwort unten
Fra

@Fra Wie ist deine Methode schneller? Es geht darum load. das alles andere als schnell. Beispielsweise ist in Methode 2 die erste Zeile mit der Produktladung unbrauchbar. Sie verwenden $productnirgendwo.
Marius

@Fra. Wenn Sie die Antwort von jemandem ablehnen, ist es eine nette Sache, einen Grund anzugeben. Was ist los mit meiner Antwort?
Marius

1
Ich könnte dasselbe für Ihre Antwort sagen ... es ist nicht der schnellste Weg. Direkte SQL-Abfragen sind der schnellste Weg. Ich denke nicht, dass Ihr Grund für ein Downvoting ausreicht. Aber Sie haben ein Recht auf Ihre Meinung.
Marius

27

Tatsächlich gibt es drei Möglichkeiten, ein Attribut für ein Produkt zu aktualisieren, ohne das gesamte Produkt zu speichern. Je nach Code / Anforderungen kann einer schneller sein als der andere.

Methode 1:

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

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

Methode 2:

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

Methode 3: (am schnellsten)

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

Alle oben genannten Methoden sind viel schneller und schonen das gesamte Produkt. Trotzdem gibt es einige wesentliche Leistungsunterschiede:

Method 1:

  • ist die schnellste, aber erforderlich, um das Produkt zu laden.
  • es löst nicht das Reindex-Ereignis aus (deshalb ist es schneller)
  • es funktioniert im Frontend

Method 2:

  • Ermöglicht die Massenaktualisierung von Produkten
    (Sie können mehrere Produkte und Attribute übergeben)
  • es löst das Massenaktionsereignis und den relativen abhängigen Neuindex aus
  • Es funktioniert nicht im Frontend

Method 3:

  • Es ist wie Methode 2, ruft jedoch keinen anderen Beobachter / Indexer auf
    (es ist also ein gemischter Ansatz zwischen Methode 1 und 2).

Methode 3 ist die flexiblere Methode, da Sie diese Produkte / Attribute manuell neu indizieren müssen. (um sie im Frontend zu aktualisieren)
Es kann nützlich sein, wenn Sie viele Produkte schnell aktualisieren und am Ende den Neuindex aufrufen möchten.
(Wenn Sie Methode 2 verwenden, wird nach dem Update für jedes Produkt ein Neuindex aufgerufen, und diese mehreren Aufrufe verlangsamen den gesamten Prozess.)

Informationen zum manuellen Neuindizieren eines einzelnen Produkts finden Sie in den von Mage_Catalog_Model_Product_Flat_Indexer bereitgestellten Funktionen wie:

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

4
Es wäre immer besser, eine negative Bewertung abzugeben ...
Fra

Nur eine kleine Anmerkung, der Wert $ sollte der
Wertcode

hmmm interessant. Methode 2 klingt großartig, nur haben Sie keine Kontrolle über das 'Feedback', was ist gelungen, was nicht? Methode 1 ist auch gut. Aber wenn ich mit dem Aktualisieren meiner Schleife über Daten fertig bin: Kann ich den Neuindex manuell aktivieren, um dies möglicherweise für bestimmte Produkt-IDs zu lösen?
snh_nl

Seltsam. Ich erhalte einen unbekannten Fehlerfilter nach Spalte `` `Gefangene Ausnahme: SQLSTATE [42S22]: Spalte nicht gefunden: 1054 Unbekannte Spalte 'catalog_product_entity.value_id' in 'field list', Abfrage lautete: SELECT catalog_product_entity. value_idFROM catalog_product_entityWHERE (entity_type_id = 4 AND attribute_id = '68 'AND entity_id = '29') `` `Das wird nicht erwartet. Läuft am 1.9.3.2
snh_nl

1
Hat mir Stunden Arbeit erspart.
dipole_moment

3

Aktualisieren

Ich suche nach der schnellsten und zuverlässigsten Methode zur Aktualisierung von Massenattributen

"Massenattribut-Aktualisierung" für Attribute oder Produkte?

Denken Sie, die Aktualisierung mehrerer Attribute ist bereits beantwortet, aber für Produkte kann dies nützlich sein ...

Wenn Sie Produkte aus der Sammlung aktualisieren möchten, sollten Sie dies nicht tun ...

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

Dadurch werden Ereignisse ausgelöst, Preisregeln und Indizes neu erstellt. Damit werden keine Ereignisse (und einige andere Dinge) übersprungen und sind viel schneller.

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

Um Preisaktualisierungen zu vermeiden, können Sie Folgendes hinzufügen:

$product->setIsMassupdate(true);

Informationen zum Aktivieren / Deaktivieren der Neuindizierung finden Sie unter 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();
    }
}

Und auch das Leeren des Caches vor der Massenaktualisierung (Produktaktualisierung) kann die Leistung steigern ...

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

Einige Zahlen vom Debuggen hier: https://github.com/Flagbit/Magento-ChangeAttributeSet/issues/16


Mage::getSingleton('catalog/product_action')->updateAttributes(...) scheint nicht die schnellste Methode zu sein ... zumindest nicht bei eingeschaltetem Mutlistore-Setup und Flat Tables ...

  • saveAttribute()

    $product = Mage::getModel('catalog/product')->load($productId);
    $resource = $product->getResource();
    $product->setData($attributeCode, $attributeValue);
    $resource->saveAttribute($product, $attributeCode);
    • Insgesamt Inkl. Wandzeit (Mikrosekunde): 437.787 Mikrosekunden
    • Insgesamt Inkl. CPU (Mikrosekunden): 423.600 Mikrosekunden
    • Insgesamt Inkl. MemUse (Bytes): 4.433.848 Bytes
    • Insgesamt Inkl. PeakMemUse (Bytes): 4.395.128 Bytes
    • Anzahl der Funktionsaufrufe: 25.711
  • updateAttributes()

    Mage::getSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array($attributeCode => $attributeValue),
        $storeId
    );
    • Insgesamt Inkl. Wandzeit (Mikrosekunde): 3.676.950 Mikrosekunden
    • Insgesamt Inkl. CPU (Mikrosekunden): 3.122.064 Mikrosekunden
    • Insgesamt Inkl. MemUse (Bytes): 8.174.792 Bytes
    • Insgesamt Inkl. PeakMemUse (Bytes): 8.199.192 Bytes
    • Anzahl der Funktionsaufrufe: 150,132
  • updateAttributes() (Ressourcen-Singleton)

    Mage::getResourceSingleton('catalog/product_action')->updateAttributes(
        array($productId),
        array( $attributeCode => $attributeValue),
        $storeId
    );
    • Insgesamt Inkl. Wandzeit (Mikrosekunde): 94.155 Mikrosekunden
    • Insgesamt Inkl. CPU (Mikrosekunden): 48.568 Mikrosekunden
    • Insgesamt Inkl. MemUse (Bytes): 1.426.304 Bytes
    • Insgesamt Inkl. PeakMemUse (Bytes): 1.370.456 Bytes
    • Anzahl der Funktionsaufrufe: 2.221

Sie können meine Antwort überprüfen, um zu verstehen, warum diese Funktion unterschiedliche Zeiten dauert ...
Fra

Nehmen Dropdown-Daten updateAttributes() (resource singleton)den tatsächlichen Admin-Wert an? oder die ID des Dropdown-Elements? (Irgendwie bekommen wir mit dieser Methode immer keinen Wert / leeren Wert, dh nichts ausgewählt
snh_nl

@snh_nl Sie müssen das ID-Komma für Mehrfachauswahl-Attribute verwenden.
SV3N
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.