Ich versuche derzeit, einige Module hinsichtlich der Leistung zu verbessern.
Einige von Ihnen kennen möglicherweise die Verwendung der walk()
Erfassungsmethode, die sehr nützlich ist, um ein direktes Durchlaufen von Produkten zu vermeiden.
Darüber hinaus und dank @Vinai kann man auch die Erfassungsmethode delete()
verwenden.
Ich habe jedoch festgestellt, dass native Magento 1-Dateien nicht immer eine dieser Methoden zum Löschen verwenden.
Einer der schlimmsten Codes, die ich je gesehen habe, ist die massDelete()
Methode, app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
mit der Produkte vor dem Löschen in eine Schleife geladen werden .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
Also habe ich einige Leistungstests durchgeführt und einige Protokollierungsaufrufe hinzugefügt, um die benötigte Zeit und die Speichernutzung für das Löschen von 100 Produkten zu überprüfen.
Test 1: walk
Methode
Ich habe den oben eingefügten Originalcode durch diesen Code ersetzt:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
Und meine Ergebnisse sind die folgenden auf meinem beschissenen Entwicklungsserver (Durchschnitt basierend auf 10 Tests):
- Originalcode: 19,97 Sekunden, 15,84 MB verwendet
- Benutzerdefinierter Code: 17,12 Sekunden, 15,45 MB verwendet
Beim Löschen von 100 Produkten ist mein benutzerdefinierter Code 3 Sekunden schneller und verbraucht 0,4 MB weniger.
Test 2: die Sammlung verwendet delete()
Methode
Ich habe den Originalcode durch diesen ersetzt:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
Und umwerfend sind hier die Ergebnisse:
- Originalcode: 19,97 Sekunden, 15,84 MB verwendet
- Benutzerdefinierter Code: 1,24 Sekunden, 6,34 MB verwendet
Beim Löschen von 100 Produkten ist mein benutzerdefinierter Code 18 Sekunden schneller und verbraucht 9 MB weniger.
Wie in den Kommentaren angegeben, scheint diese Methode weder die Magento-Ereignisse (nach dem Laden, nach dem Löschen) noch den Index- / Cache-Flush auszulösen.
Frage
Meine Frage lautet also: Gibt es einen Grund, warum das Magento-Kernteam walk('delete')
die Erfassungsmethode oder das Ereignis nicht besser delete()
verwendet hat, anstatt Produkte in einer Schleife zu laden (von der wir alle wissen, dass sie eine sehr, sehr schlechte Praxis ist)?
Hauptziel ist es, solche Schlüsselpunkte im Falle einer Modulentwicklung zu kennen: Gibt es bestimmte Fälle, in denen man die walk
/ collection- delete()
Methode nicht verwenden kann ?
BEARBEITEN: Der Grund liegt definitiv nicht darin, dass das catalog_controller_product_delete
Ereignis ausgelöst wird, da derselbe Code an mehreren Stellen (überprüfen Sie die massDelete
Methoden) im Magento-Kern gefunden werden kann. Ich habe das Beispiel von Produkten verwendet, um die Leistung hervorzuheben, da es sich normalerweise um die größten Einheiten handelt
delete()
führt eine DELETE-Abfrage durch, anstatt die Sammlung zu laden und jedes Produkt zu löschen. Mit diesem verlieren Sie wirklich die Ereignisse.
getSingleton()
als Leistungsmaß anstelle der offensichtlichen Verwendung der Sammlung. Oh, und es ist möglich, das Ereignis auch mit einer Sammlung auszulösen, nur nicht mit derwalk()
Verknüpfung.