J'essaie actuellement d'améliorer quelques modules concernant les performances.
Certains d'entre vous connaissent peut-être l' utilisation de la walk()
méthode de collecte, ce qui est très utile pour éviter de parcourir directement les produits.
En plus de cela et grâce à @Vinai, on peut également utiliser la delete()
méthode de collecte .
Mais j'ai remarqué que les fichiers natifs de Magento 1 n'utilisent pas toujours l'une de ces méthodes pour la suppression.
L'un des pires codes que j'ai vus est la massDelete()
méthode à partir de app/code/core/Mage/Adminhtml/controllers/Catalog/ProductController.php
laquelle les produits sont chargés dans une boucle avant la suppression .
foreach ($productIds as $productId) {
$product = Mage::getSingleton('catalog/product')->load($productId);
Mage::dispatchEvent('catalog_controller_product_delete', array('product' => $product));
$product->delete();
}
J'ai donc fait quelques tests de performances, ajouté quelques appels de journalisation pour vérifier le temps pris et l'utilisation de la mémoire pour la suppression de 100 produits.
Test 1: walk
méthode
J'ai remplacé le code d'origine collé ci-dessus par ce code:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->walk('delete');
Et mes résultats sont les suivants sur mon serveur de développement merdique (moyenne basée sur 10 tests):
- Code d'origine: 19,97 secondes, 15,84 Mo utilisés
- Code personnalisé: 17,12 secondes, 15,45 Mo utilisés
Ainsi, pour la suppression de 100 produits, mon code personnalisé est 3 secondes plus rapide et utilise 0,4 Mo de moins.
Test 2: utilisation de la delete()
méthode de collecte
J'ai remplacé le code d'origine par celui-ci:
$collection = Mage::getResourceModel('catalog/product_collection')
->addAttributeToSelect('entity_id')
->addIdFilter($productIds)
->delete();
Et les résultats sont époustouflants :
- Code d'origine: 19,97 secondes, 15,84 Mo utilisés
- Code personnalisé: 1,24 seconde, 6,34 Mo utilisés
Donc, pour la suppression de 100 produits, mon code personnalisé est 18 secondes plus rapide et utilise 9 Mo de moins.
Comme indiqué dans les commentaires, il semble que cette méthode ne déclenche pas les événements Magento (après chargement, après suppression) ni le vidage d'index / cache.
Question
Ma question est donc la suivante: y a-t-il une raison pour laquelle l'équipe principale de Magento n'a pas mieux utilisé la méthode de walk('delete')
collecte de l'événement ou au delete()
lieu de charger les produits en boucle (ce que nous savons tous est une très très mauvaise pratique)?
L'objectif principal est de connaître ces points clés en cas de développement d'un module: y a-t-il des cas particuliers où l'on ne peut pas utiliser la méthode walk
/ collection delete()
?
EDIT: la raison n'est certainement pas à cause de l' catalog_controller_product_delete
événement envoyé car le même code peut être trouvé à plusieurs endroits (vérifiez les massDelete
méthodes) dans le noyau Magento. J'ai utilisé l'exemple des produits pour mettre en évidence les performances car ce sont généralement les plus grandes entités
delete()
effectue une requête DELETE au lieu de charger la collection et de supprimer chaque produit. Avec celui-là, vous perdrez vraiment les événements.
getSingleton()
comme mesure de performance, au lieu de l'utilisation évidente de la collection. Oh, et il est également possible de déclencher l'événement avec une collection, mais pas avec lewalk()
raccourci.