4 ms·
> The problem I had with the bullet gem however is that some times you actually want N+1 queries. Especially with Russian-Doll caching. I know it sounds like I
by nathan_long 8y ago
> The problem I had with the bullet gem however is that some times you actually want N+1 queries. Especially with Russian-Doll caching.
I know it sounds like I keep beating the same drum, but to me this problem seems like "we have slow views, therefore we need to sprinkle conditional caching logic everywhere, therefore we need to allow lazy loading, therefore we need to watch for N+1 queries."
As I wrote elsewhere (http://nathanmlong.com/2016/11/elixir-and-io-lists-part-2-io-lists-in-phoenix/ http://nathanmlong.com/2016/11/elixir-and-io-lists-part-2-io...):
> By contrast, by compiling templates to functions, Phoenix automatically and universally applies this simple view caching strategy: the static parts of our template are always cached. The dynamic parts are never cached. The cache is invalidated if the template file changes. The end.
With fast views, no lazy loading is needed and no N+1 queries need to be possible. I don't think this is a problem inherent to Ruby, just to the way ActionView and ActiveRecord currently work.
- gingerlime 8y agoThat's interesting to learn... I always assumed caching is a necessary evil if you want to speed things up. I certainly feel like rendering views is rails is slower than I'd like it to be (talking about the rendering part alone), especially with partials. How do you deal with views that pull dynamic data that produce a heavy query however?
- nathan_long 8y agoIf the query was expensive and could be run periodically, I'd either create a materialized view that gets refreshed as often as necessary (maybe by https://dockyard.com/blog/2017/11/29/need-an-elixir-dependency-to-manage-recurring-jobs-not-so-fast https://dockyard.com/blog/2017/11/29/need-an-elixir-dependen...) or use a GenServer process for caching that data (as you might do with Redis otherwise). I don't think the view rendering itself would ever be a performance issue, but rendering a view is just a function call in Phoenix, so I could take a similar approach there - store it in a GenServer.