Reputation: 800
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
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