Is there any way to speed up this Magento code? Currently it is looking through about 2k products and takes approximately 20 minutes to run.
I’m guessing the issue is around the product->load() call, but I’m not familiar enough Magento to know the overhead it takes.
Thank you.
from controller
Mage::dispatchEvent(
'category_rule_save',
array(
'rule_id' => $id,
'attribute_code' => $data['attribute_code'],
'operator' => $data['operator'],
'value' => $data['value'],
'category_id' => $data['category'],
'store_id' => $data['store_id']
)
);
from Observer.php
public function onCategoryRuleSave($observe)
{
$collection =
Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect($observe['attribute_code']);
$write = Mage::getSingleton('core/resource')->getConnection('core_write');
foreach ($collection as $product) {
$productId = $product->getId();
$product = $product->load($productId);
$productAttributeValue = '';
$productAttributeValue =
Mage::getModel('catalog/product')->load($productId)
->getAttributeText( $observe['attribute_code'] );
$r = 0;
if ( is_numeric($observe['value']) ) {
switch($observe['operator']) {
case "<":
$r = ($productAttributeValue < $observe['value']) ? 1 : 0;
break;
case ">":
$r = ($productAttributeValue > $observe['value']) ? 1 : 0;
break;
case "<=":
$r = ($productAttributeValue <= $observe['value']) ? 1 : 0;
break;
case ">=":
$r = ($productAttributeValue >= $observe['value']) ? 1 : 0;
break;
case "==":
$r = ($productAttributeValue == $observe['value']) ? 1 : 0;
break;
case "!=":
$r = ($productAttributeValue != $observe['value']) ? 1 : 0;
break;
}
}
else {
switch($observe['operator']) {
case "==":
$r = (
strcmp(strtolower($productAttributeValue) , strtolower($observe['value'])) == 0
) ? 1 : 0;
break;
case "!=":
$r = (
strtolower($productAttributeValue) != strtolower($observe['value'])
) ? 1 : 0;
break;
}
}
if ($r==1) {
$write->query(
"REPLACE INTO `catalog_category_product` (`category_id`, `product_id`)
VALUES (" . $observe['category_id'] . "," . $product->getId() . ")"
);
}
}
}
Try replacing the product loading with:
You’re loading a product object 2 extra times. The $product variable in the foreach already is the loaded product with the attribute that you need to work with. Loading a $product object with all of its attributes is expensive given Magento’s EAV database structure.