2012-07-10 10 views
10

Tengo un método de ayuda en Magento que me obliga a obtener el recuento de varias colecciones no relacionadas. Además de esto, necesito esta información para cada producto en una categoría, es decir, para cada producto en la vista de lista de productos. Así que potencialmente crearé muchas colecciones repetidamente durante la representación de la lista de productos.Magento: método más eficaz para obtener un recuento de colecciones

¿Cuál es el método más eficiente para obtener el recuento de una colección, es decir, no necesito ningún dato de los modelos, simplemente cuántos modelos hay?

¿Es simplemente:

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

O hay una manera más eficiente de hacer esto?

Respuesta

-13

Muy buena pregunta. De lo que he encontrado en el código fuente, esta es la opción más rápida, a pesar de que hace lo siguiente en Varien_Data_Collection:

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

Por lo que hace su cosa habitual y va adelante y cargas lo que ha especificado, al igual que lo haría hacer si itera sobre los elementos individuales. No hay magia SQL COUNT() aquí. Los únicos otros métodos que he encontrado que tienen algo que ver con el conteo de productos son getSelectCountSql() y getProductCountSelect(), pero simplemente devuelven el código SQL.

Pero: todo lo de EAV y el generador de consultas de Magento son muy inteligentes, por lo que no debería ser que es un gran negocio. Además, apostaría a que Magento tiene todo tipo de almacenamiento en caché.

En resumen: sí, es la opción más rápida para contar la cantidad de productos en una colección de productos.

+5

-1: Este no es el más rápido. Ocurre justo lo contrario. En colecciones grandes, esto solo bloquea PHP debido al límite de memoria, por lo que lleva una cantidad infinita de tiempo en comparación con el método 'getSize()'. – hakre

1

Trate como:

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

Para contar los elementos de una colección, utilice el getSize() método:

$collection->getSize(); 

Nunca utilizar la función de php count() o el método count() de la colección como esto:

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

Cuando utiliza la función/método count(), Magento carga todos los elementos de la colección de la base de datos. En las grandes colecciones que tendrá un gran uso de memoria y problemas posiblemente como Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 71 bytes) ...

+1

De acuerdo! Gracias por el consejo, FLOZz! Nunca use count(). Al trabajar con miles de elementos en la recopilación, el uso de conteo() puede hacer que su tienda se cuelgue. Descubrí por el camino difícil ... – awaage

+0

bonitos consejos de 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); 
    } 

por lo getSize() no es más eficiente.

+1

Probablemente deberías explicar tu código un poco más. ¿Qué archivo estás mirando? No veo una función como esa en ninguna parte de la carpeta de la aplicación en la versión 1.7. –

+1

Lo sentimos, pero esto es simplemente erróneo, por favor ver las métricas de rendimiento siguientes: Usando count(): 2014-07-07T12: 27: 04 + 00: 00 de depuración (7): Tiempo de ejecución: 0.4933660030365 Usando getSize (): 2014-07-07T12: 28: 56 + 00: 00 DEBUG (7): Tiempo ejecutado: 0.22210693359375 Como puede ver, getSize() es significativamente más eficiente. – evensis

+0

'public function getSize() {...; $ this -> _ totalRecords = $ this-> getConnection() -> fetchOne ($ sql, $ this -> _ bindParams); ...; return intval ($ this -> _ totalRecords); } ' no sé dónde obtuvo su código, pero este es el código que se usa para la mayoría de las cosas en' lib/Varien/Data/Collection/Db.php', y es un solo sql 'select count (. ...) de ...; 'consulta, obviamente más rápido. – user3338098

0

Aquí es la forma más eficiente de hacer esto, utilizando una función en los métodos de 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)); 
Cuestiones relacionadas