I need to process a product collection and update the stock quantity and status for each product.
Currently I'm doing this:
foreach($products AS $product) {
$quantity = $productQuantities[$product->getId()]; // A helper array that I've built before
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->setData('is_in_stock', $quantity > 0 ? 1 : 0)->setQty($quantity)->save();
}
This works nicely, but I reach memory exhaustion after about 5k products, and I need to update more than 20k products.
Is there any Magento-internal way of avoiding this?
I do realize I could write directly to the DB, but I'd rather avoid this and go with a Magento-internal function.
Best Answer
Avoid saving entire objects
One of the biggest problem in your case is that you save the entire stock item every time.
It's not performance friendly.
For some models, Magento provides a
saveAttribute
method which can save you a lot of resources, however it does not exist for thecataloginventory/stock_item
model.So I reckon you should implement it via a custom module:
In your
config.xml
, you first need to override the resource model:Then in your
Model/CatalogInventory/Resource/Stock/Item.php
file:Now in your code, replace:
With:
Avoid loading entire objects
Another issue in your case, is that you load entire objects.
Same as the load, it's pretty bad in terms of performance.
As you're dealing with 20k products, I'm not sure how it will work but maybe using collections will save you some time.
So instead of :
Maybe you should try:
Where
$productIds
is an array containing all your product ids.Avoid looping a collection
I don't know what your
$products
variable is but if it is a collection, I suggest you should avoid looping on it.Magento provides a great iterator walk method with callback method to handle massive collection.
So instead of:
You should try:
Then declare the following method in your class:
Note that you will have to make your
productQuantities
array accessible globally in your class to be able to do so.More information about the walk iterator: http://inchoo.net/magento/working-with-large-magento-collections/