WombaT
WombaT

Reputation: 800

Symfony 2 second level cache enabled but not being used?

I have list of records which have at least one related entity. On record list I display main list and data from related records so if table has ~100 records doctrine generates and executes ~150 queries: one for list and one for each related entity which is not great thing. It can be easily reduced to just 2 queries: one for list and one for all related entities at once.

As I found, second level cache in doctrine would be perfect for such case.

So, I have enabled cache in config:

doctrine:
  orm:
    second_level_cache:
      enabled: true

And added to all entities annotation @ORM\Cache(usage="READ_ONLY"). Then before generating list I am fetching all records form both tables:

$this->getDoctrine()->getRepository('AppBundle:Refuel')->findAll();
$this->getDoctrine()->getRepository('AppBundle:FuelType')->findAll();

As I hoped they will got cached and durign actual list render reused without generating ~150 queries. But it is not a case. Debug panel shows that there are still ~150 queries executed and cache stats are:

Hits: 0
Misses: 2
Puts: 319

So as I guess entities are being cached but not reused. Why?

All i found already about second level cache is related to redis - do not want to use it - is redis required to use that cache?

It is sad that there is so little documentation on how to configure that.

Upvotes: 2

Views: 3233

Answers (1)

beterthanlife
beterthanlife

Reputation: 1658

Just to expand on @BDS and @Jakub's comments, who have the right answers, if you only do one thing it should be to change your query to eager loading (note that we are selecting both entity types in our query so all records will be fetched in one go):

$refuel= $this->m_em
        ->getRepository('AppBundle:Refuel')
        ->createQueryBuilder('r')
        ->select('r,t')
        ->join('r.fuel_type', 't')
        ->getQuery()
        ->getResult();

Once you've done that, you can start to look at utilising the second level cache. For that, you need to specify the cache driver in your config[_prod].yml:

second_level_cache:
  region_cache_driver:
    type: memcache
  enabled: true
  log_enabled: false
  regions:
    my_region:
      cache_driver: memcache
      lifetime: 3600

And then add annotations to your cachable entities:

/**
 * @ORM\Entity
 * @ORM\Table(name="fos_user")
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE", region="my_region")
 */

Upvotes: 4

Related Questions