Magento how to cache a productCollection
Asked Answered
U

2

6

Ive noticed my home page is taking a long time to load - over 6 seconds infact according site24x7.com, so ive been switching elements off to try and determine what is the cause, and it is down to 2 product collection files I have made to show new products and best selling products.

As soon as i remove these from the home page, the page loads in less than .5 seconds.

So, can anyone help with optimising and caching a productCollection? I have APC installed and running on the server, but Im not sure it is caching the files located in app/design/frontend/default/MY_THEME/catalog/product/newproducts.phtml

So, my collection call for best selling (most viewed actually) looks like this;

    <?php $storeId = Mage::app()->getStore()->getId(); // return current store id  ?>
    <?php $_productCollection= Mage::getResourceModel('reports/product_collection')
    ->addAttributeToSelect('*')
    ->addStoreFilter($storeId)
    ->addViewsCount()
    ->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
    ->addFieldToFilter('status',Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
    $_productCollection->getSelect()->limit(8)
    ?>

How can I further optimise this?

Unmanned answered 14/3, 2013 at 11:30 Comment(0)
S
8

Try

  $storeId = Mage::app()->getStore()->getId(); 
  $cache = Mage::getSingleton('core/cache');
  $key = 'homepage-most-view-' . $storeId;

  if(! $data = $cache->load($key)){
      $_productCollection= Mage::getResourceModel('reports/product_collection')
      ->addAttributeToSelect('*')
      ->addStoreFilter($storeId)
      ->addViewsCount()
      ->addFieldToFilter('visibility', Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH)
      ->addFieldToFilter('status',Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
      $_productCollection->getSelect()->limit(8)
      // get the element you need from  $_productCollection and store in $array
      $data = serialize($array);
      $cache->save(urlencode($data), $key, array("homepage_cache"), 60*60*24);
  }
  else{
      $data = unserialize(urldecode($data)); 
 }

See

Soluk answered 14/3, 2013 at 12:52 Comment(6)
@R.S Why do you use urlencode twice? Is it necessary or is it a bug here? Shouldn't this be: $data = urlencode(serialize($array)); $cache->save($data, $key, array("homepage_cache"), 60*60*24); ?Fetish
It was a typo.. fixed nowSoluk
Mage::app()->getCache() instead of Mage::getSingleton('core/cache') can save you a lot of time...Fibre
Why are you url encoding at all?Saltarello
I'm also seeing that I am unable to cache a product collection. I guess why that's you are storing it into an array. Does magento prevent serializing product collections because they are too large?Saltarello
Not working, not getting product collection after getcacheHorace
G
5

If you want to cache $collection, there is already a built-in possibility for collection caching in Magento.

 $_productCollection= Mage::getResourceModel('reports/product_collection');

$cache = Mage::app()->getCache(); //Let's get cache instance
        $cache->setLifetime(86400); //Here we set collection cache lifetime
        $_productCollection->initCache(
            $cache,
            'Bestsellers_', //this is just custom prefix
            array('collections') 
        );
    }

Credit for above code: apiworks.net (http://www.apiworks.net/2015/01/magento-collection-caching.html)

Gaspar answered 11/1, 2017 at 8:12 Comment(3)
in this example I understand how top set it. But is there logic we need to implement the 2nd run to check if a cache exists and only then save it to cache ... or does "cache know/do this of there own" thhx!Ondometer
Hi,@snh_nl. As you can see in the following code , which is part of Varien_Data_Collection_Db class: collabshot.com/show/H0q3bn Magento tries to load from the cache first and then if fails, it loads from database and saves the cached version. So, the answer is: for the same $collection object, you don't need to do anything else once you initialised the cache using the code above. It will automatically load next time for you.Epicardium
Could we use the code like this gist.github.com/seansan/1397a892fa496d5b5f98c2d85e4fa82e in a html template file? Or how would one cache a collection call in a phtml file (for instance product listing)Ondometer

© 2022 - 2024 — McMap. All rights reserved.