2012-07-10 7 views
10

Ho un metodo di supporto in Magento che mi richiede di ottenere il conteggio di numerose raccolte non correlate. Oltre a ciò, ho bisogno di queste informazioni per ogni prodotto in una categoria, ad esempio per ciascun prodotto nella visualizzazione elenco prodotti. Quindi, potenzialmente, creerò molte raccolte ripetutamente durante il rendering dell'elenco dei prodotti.Magento - Il metodo più efficiente per ottenere un conteggio delle collezioni

Qual è il metodo più efficiente per ottenere il conteggio di una raccolta, ovvero, non ho bisogno di dati dai modelli, semplicemente quanti modelli ci sono.

è semplicemente:

Mage::getResourceModel('mymodule/mymodel_collection')->addFilter('myattribute', $value)->count() 

o c'è un modo più efficace per fare questo?

risposta

-13

Ottima domanda. Da quello che ho trovato nel codice sorgente, questa è l'opzione più veloce, anche se lo fa presente quanto segue Varien_Data_Collection:

public function count() 
{ 
    $this->load(); 
    return count($this->_items); 
} 

in modo che la sua solita cosa e va avanti e carichi qualunque specificati, proprio come farebbe fai se hai ripetuto i singoli elementi. Nessun codice SQL magico COUNT() qui. Gli unici altri metodi che ho trovato che hanno qualcosa a che fare con il conteggio dei prodotti sono getSelectCountSql() e getProductCountSelect(), ma restituiscono solo il codice SQL.

Ma: l'intera cosa EAV e il generatore di query di Magento sono molto intelligenti, quindi non dovrebbe essere quello grande di un affare. Inoltre, scommetto che Magento ha tutti i tipi di memorizzazione nella cache in corso.

Quindi in breve: sì, è l'opzione più veloce per contare il numero di prodotti in una raccolta di prodotti.

+5

-1: Questo non è il più veloce. L'opposto è il caso. Nelle raccolte di grandi dimensioni questo si blocca semplicemente PHP a causa del limite di memoria, quindi richiede un tempo infinito di tempo in più rispetto al metodo 'getSize()'. – hakre

1

Prova come:

$collection = Mage::getResourceModel('mymodule/mymodel_collection')->addFieldFilter('myattribute', $value); 
$collection->count(); 
//or 
$collection->getSize(); 
64

Per contare gli elementi in una collezione, utilizzare il metodo getSize():

$collection->getSize(); 

Non utilizzare la funzione php count() o il metodo count() della collezione come this:

count($collection) 
$collection->count() 

Quando si utilizza la funzione/metodo count(), Magento carica tutti gli elementi della raccolta dal database. Su grandi collezioni si avrà un utilizzo della memoria enorme e le questioni, eventualmente, come Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 71 bytes) ...

+1

Accetto! Grazie per il suggerimento, FLOZz! Non usare mai count(). Quando si lavora con migliaia di elementi nella raccolta, l'uso di count() può causare l'arresto anomalo del negozio. L'ho scoperto nel modo più duro – awaage

+0

buoni consigli di FLOZz –

-1
/** 
    * Retrieve collection all items count 
    * 
    * @return int 
    */ 
    public function getSize() 
    { 
     $this->load(); 
     if (is_null($this->_totalRecords)) { 
      $this->_totalRecords = count($this->getItems()); 
     } 
     return intval($this->_totalRecords); 
    } 

così getSize() non è più efficiente.

+1

Probabilmente dovresti spiegare un po 'di più il tuo codice. Che file stai guardando? Non vedo una funzione del genere in nessuna parte della cartella dell'app nella versione 1.7. –

+1

Spiacente, ma questo è semplicemente sbagliato, si prega di vedere le metriche di performance di seguito: Utilizzando count(): 2014-07-07T12: 27: 04 + 00: 00 DEBUG (7): Tempo di esecuzione: ,4933660030365 Utilizzando getSize (): 2014-07-07T12: 28: 56 + 00: 00 DEBUG (7): Tempo eseguito: 0,22210693359375 Come potete vedere, getSize() è significativamente più efficiente. – evensis

+0

'public function getSize() {...; $ this -> _ totalRecords = $ this-> getConnection() -> fetchOne ($ sql, $ this -> _ bindParams); ...; return intval ($ this -> _ totalRecords); } ' non so dove hai preso il tuo codice, ma questo è il codice che è usato per la maggior parte delle cose è in' lib/Varien/Data/Collection/Db.php', ed è un singolo conteggio di selezione sql (. ..) da ...; 'query, quindi ovviamente più veloce. – user3338098

0

Ecco il modo più efficace per fare questo, utilizzando costruito in metodi Magento:

$ids = Mage::getModel('catalog/product') 
       ->getCollection() 
       ->addAttributeToSelect('entity_id') 
       ->addFieldToFilter('status', array('eq'=>'1')) 
       ->addFieldToFilter('visibility', array('eq'=>'4')) 
       ->addFieldToFilter('type_id', array('in'=>array('simple'))) 
       ->getAllIds(); 
     var_dump(count($ids)); 
Problemi correlati