Cache In Active Records

I want to ask if there is an easy way to cache db-query of active records.

For example: 2 Models: Region and Shop

The Shop-model has a relation to Region (every Shop belongs to one Region).

With the GridView I select all Shops in one Region:

Shop->Name - Shop->Region->Name

Shop 1 - New York

Shop 2 - New York

Shop 3 - New York

For every Shop Yii starts a new Query to get the Region although every time it is the same Query to get the Region:

SELECT * FROM Region WHERE 1

So is there a way to implement a cache to active records?

Thanks…

Hope you have gone through the caching guide for yii 2 and the cache dependency and data and query caching section. Is there a specific query you have in that?

Yes, I already implemented Cache e.g. cache the result of a query.

But I wonder if there is an easy way to implement cache to active record-models (extend the actice record model) e.g. if I load the same model every 5 seconds it should not be loaded from db, but from cache…

The first time I load


$region = Region::findOne(1); 

it is loaded from db. The second time from cache…

Thanks… by the way (off-topic): your extensions are great…

I will let a Yii Dev/Expert answer here… but IMHO…

I think caching AR models (other than its queries) may not always be needed within the same session - based on the way you access it. I think If you need you can cache specific data out of each AR model and reuse it.

For the same session, You may eager load (check this section) and have just one database fetch as it is accessible across the session (as long as you pass these variables between your actions).

For different sessions - I feel you can write your own find wrapper method to read from cache before calling the AR find method. Or maybe you can wait for other better answers.

You are welcome

Honestly, there’s no point in doing this. Simple lookup queries (based on the indexed id field) will be extremely fast and caching them will offer almost nothing in terms of performance. The term for this is “premature optimization”.

What you want to do instead is to write your application, benchmark it, find the slow code paths, and then start optimizing/caching.

"Programmers waste enormous amounts of time thinking about, or worrying about, the speed of noncritical parts of their programs, and these attempts at efficiency actually have a strong negative impact when debugging and maintenance are considered. We should forget about small efficiencies, say about 97% of the time; premature optimization is the root of all evil. Yet we should not pass up our opportunities in that critical 3%."

-Donald Knuth, Structured Programming With go to Statements

Edit: In your case, I would probably just cache the entire region table into Yii::$app->cache and get results from that. This way, it works even if you have multiple regions in your GridView results.