What does HackerNews think of bullet?

help to kill N+1 queries and unused eager loading

Language: Ruby

There's a Ruby gem called Bullet that identifies and warns developers about N+1 problems. You can also have it fail tests if detected.

I don't know if the approach is possible with every ORM or if it's just leveraging some Ruby perks, but I can't think of a good reason why you wouldn't use the equivalent everywhere.

https://github.com/flyerhzm/bullet

As a Rails developer, recently I found Bullet [0] which helps massively in dealing with eager loading. For some reason I expected the framework to manage this sort of thing for me, even when Rails actually does a ton out of the box already. Only while refactoring I picked up on queries dragging performance. Oh well...

[0] https://github.com/flyerhzm/bullet

This is a popular trope, but in practice it's just as easy to do n+1 via your own abstractions where "items.each { |i| i.foo }" happens to do it too. Without any ORM involved. Everyone will do it sometimes and the question is only whether you're going to spot it before it causes an outage. (In many cases it will only cause a slight slowdown)

At least there are tools to warn you about n+1 automatically https://github.com/flyerhzm/bullet

> Ecto prevents N+1 queries by default, which I think is clearly better.

To be fair...

If you want to protect yourself from these with Rails you can install Bullet[0] and get protection through in your face notifications, and you have the option to let it slide because you're taking advantage of caching with Rails and in this case you know what you're getting into and the N+1 query with caching ends up being better because you understand your domain.

Rails also has the strong migrations[1] gem which is a huge help for not shooting yourself in the foot for running migrations in production by helping you avoid table locks and other issues / errors. But AFAIK there's no Ecto equivalent, but strong migrations is really really useful.

Rails also has the data-migrate[2] gem which is a nice little abstraction for splitting out your schema changes and backfilling data in an automated way. There's nothing like this with Ecto. This one isn't as useful as strong migrations IMO but it's still very handy to have this problem taken care of for you without having to re-invent a new strategy in every project or copy code over.

Basically all 3 of these things are something I'd use in every Rails project but with Phoenix I wouldn't have these things except for N+1 query protection.

I'm pretty sure you could technically create strong migrations and data-migrate for Ecto but the reality of the situation is today neither of them are available and there's no sign of them coming anytime soon. Meanwhile strong migrations has had ~6 years worth of real world testing at this point.

[0]: https://github.com/flyerhzm/bullet

[1]: https://github.com/ankane/strong_migrations

[2]: https://github.com/ilyakatz/data-migrate

It is a plugin/gem that helps you track N+1 queries.

https://github.com/flyerhzm/bullet

Looks like the bullet gem does what you want.

https://semaphoreci.com/blog/2017/08/09/faster-rails-elimina...

https://github.com/flyerhzm/bullet

EDIT: It looks like this was already mentioned in another thread. I guess I don't understand the issue if that doesn't solve your problem.

Yes, exactly!

> could also ORM code with N+1 queries

Oh, they absolutely do, and when we're lucky they actually catch them on their own before they get to code review. Some folks reach for tools like Bullet [0] and, that's great, but unfortunately, sometimes they treat that tooling like the Holy Gospel. They develop an over-reliance on them as if those tools exist to offload critical thinking. Drives me crazy... in my experience, it's been hard to combat this type of thing, too. The pace of "agile," the calculus between paying down technical debt and mentoring and progress, I don't really know why but I haven't had a lot of long-term luck.

> One of the problems, in my opinion, is that SQL isn't "cool" or hip and by many seen as not important to learn.

I think you're really right about that. I happen to like writing SQL quite a bit and I take a little bit of pride in that I kind of sort of actually understand a little about what is going on in the database and even then I neglect that skill. I picked up copies of both "SQL Anti-Patterns" and "SQL Performance Explained" based on recommendations from this thread and am eager to get in to them this weekend. Still lots to learn... And, I have some SQL problems that I can see coming up over the horizon today and I hope this gives me the edge I need to start grappling with them sooner rather than later.

[0]: https://github.com/flyerhzm/bullet

Also if you want something to pull your ear when you're fudging things up, use the Bullet gem.

Literally, just add this initializer in your development.rb

    config.after_initialize do
      Bullet.enable = true
      Bullet.alert = true
      Bullet.bullet_logger = true
      Bullet.console = true
      Bullet.growl = true
      Bullet.xmpp = { :account  => '[email protected]',
                      :password => 'bullets_password_for_jabber',
                      :receiver => '[email protected]',
                      :show_online_status => true }
      Bullet.rails_logger = true
      Bullet.airbrake = true
    end
https://github.com/flyerhzm/bullet

>The Bullet gem is designed to help you increase your application's performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you're using eager loading that isn't necessary and when you should use counter cache.

Here's few other ways to optimize your rails application (with the description taken from the doc) :

- https://github.com/flyerhzm/bullet/ : The Bullet plugin/gem is designed to help you increase your application’s performance by reducing the number of queries it makes. It will watch your queries while you develop your application and notify you when you should add eager loading (N+1 queries), when you’re using eager loading that isn’t necessary and when you should use counter cache.

- https://github.com/sdsykes/slim_scrooge/ : SlimScrooge implements inline query optimisation, automatically restricting the columns fetched based on what was used during previous passes through the same part of your code.

- http://guides.rubyonrails.org/caching_with_rails.html : Caching With Rails from the awesome rails guides

- http://guides.rubyonrails.org/performance_testing.html : Performance Testing Rails Applications from the rails guides