Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

Yep, I used it extensively on one project, configuring it to raise exceptions if it detected an N+1 query and gradually enabling it test by test as I fixed them. It's very helpful.


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 want my cache key to be lean, only fetching one record without its associations, because if the data is cached, I don't need any further queries anyway. If I "fix" my N+1 queries and load all associations, I actually negate the benefits of the nested caching and incur a cost I can avoid.


> 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...):

> 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.


That'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?


If 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-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.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: