No momento, estou reutilizando muitas coleções aninhadas nos loops foreach. É possível subir essas coisas alguns níveis? Atualmente, sou forçado a recarregar coleções com mais de 51k entidades, o que torna as coisas tremendamente mais lentas. Especificamente as coleções do kitinventory.
<?php
class Codespace_Module_Helper_Item extends other_one{
function functionOne($collection){
...
$data = $collection->getData();
foreach($data as $item){
$this->_functionTwo($item);
}
...
}
function _functionTwo($item){
$model = Mage::getModel('catalog/product');
$id = $model->getIdBySku($item['sku']);
$inventoryStatus = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($id, 'product_inventory_status', 1);
$invStatus = $model->getResource()->getAttribute('product_inventory_status')->getSource()->getOptionText($inventoryStatus);
if ($invStatus && $id) {
if ($invStatus !== 'Z') {
$stockItem = Mage::getModel('cataloginventory/stock_item');
$stockItem->setData(array());
$stockItem->loadByProduct($id);
if ($stockItem->getQty() != $item['quantity']) {
$stockItem->setQty(item['quantity']);
$stockItem->save();
$this->functionThree($item['sku']);
}
}
}
}
function functionThree($sku){
$collectionOfKits = Mage::getModel('kitinventory/kitinventory')->getCollection()->addFieldToFilter('related_sku',$sku);
if($collectionOfKits->getSize()){
foreach($collectionOfKits as $kit){
$kitSku = $kit->getSku();
$kitCollection = Mage::getModel('kitinventory/kitinventory')->getCollection()->addFieldToFilter('kit_sku',$kitSku)->setOrder('related_sku','ASC');
...
foreach($kitCollection as $component){
$componentSkus[] = $component->getRelatedSku();
$componentRequiredQuantity[] = $component->getRequiredQuantity();
}
$componentProductCollection = Mage::getModel('catalog/product')->getCollection();
$componentProductCollection->joinField('qty',
'cataloginventory/stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left');
$componentProductCollection->addAttributeToFilter('sku', array('in' => $componentSkus));
foreach($componentProductCollection as $component){
$quantity = $component->getQty();
...
}
$kitId= Mage::getModel('catalog/product')->getIdBySku($kitSku)
$kitStockItem = Mage::getModel('cataloginventory/stock_item')->loadByProduct($kitId);
$this->functionFour($kitStockItem,$kitSku,$amountOfKitsPossible);
}
}
}
function functionFour($kitStockItem,$kitSku,$amountOfKitsPossible){
...
$kitStockItem->setQty($quantity);
$kitStockItem->save();
...
}
EDIT: esta é a funcionalidade atual que eu criei, ainda acho que existe uma maneira melhor de lidar com essas coleções.
collection
model
object
easymoden00b
fonte
fonte
functionOne($collection)
? Em que ordem seria o tamanho / número de itens? É necessário fazer um loop sobre ele para obter os SKUs?Respostas:
Existem algumas coisas em que você pode trabalhar;
&
na declaração de parâmetro de função comofunction hello(array &$world)
if
declarações mais inteligentes para obter menos recuo->cleanModelCache()->clearInstance()
deMage_Core_Model_Model_Abstract
para limpar os dados subjacentes para alguns objetos, pode acelerar as coisas.Adicionada uma versão atualizada do seu código com algumas recomendações embutidas no seu código atual, eu poderia continuar um pouco, mas atualmente não adicionaria mais.
Função 1: Objetivo é caminhar pela coleção
Função 2: Objetivo é atualizar o estoque se alterado
Função 3: Objetivo de atualizar itens de estoque relacionados
Função 4: teve que fazer algumas suposições de sorte (ou azar), pois agora é uma função inútil, pode ser adicionada como na Função 3.
fonte
Eu queria adicionar isso como um comentário, mas ainda não tenho representante suficiente. Veja como as redes principais do Magento associam a quantidade do produto à coleção de catálogos / produtos aqui: https://github.com/OpenMage/magento-mirror/blob/magento-1.9/app/code/core/Mage/Adminhtml /Block/Catalog/Product/Grid.php#L65
Se você ingressar na tabela para obter o qty, não precisará chamar isso em um loop:
Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
A outra alternativa é verificar se você pode armazenar em cache os resultados desse processo intensivo do sistema. Talvez você possa criar uma segunda tabela de banco de dados para armazenar os resultados e atualizá-la como faria um índice magento.
fonte
Você não precisa recarregar o modelo repetidamente,
Mage::getModel()
basta uma referência sem saber como é difícil dizer se seus modelos de recursos são difíceis de dizer se ele é reinicializado toda vez na memória e nesses loops você acaba vazando / ficando sem memória causando possível troca de disco.Uma coleção para governar todos eles. Refatorando as funções para fazer referência apenas a uma coleção. É o mesmo com SQL padrão e programação procedural. Demore um pouco mais a investigar suas coleções e modelos de recursos sobre como você pode obter todos os dados necessários do SQL uma vez, talvez duas vezes e, em seguida, ter memória suficiente no local, além de referenciar os dados para fazer o loop para exibição / manipulação. Também é mais fácil armazenar um resultado no cache do que muitos, esse também é o caso dos mecanismos de cache internos do MySQL, pois solicitações frequentes que são grandes o suficiente causam o mesmo problema de troca de disco.
Salve a E / S
Vinai tem um bom exemplo de implementação da mesma abordagem:
Referências :
fonte