Dealing with the n+1 problem in Laravel

Поделиться
HTML-код
  • Опубликовано: 26 май 2021
  • Dealing with the n+1 problem in Laravel by using the $with model attribute and the newly added Model::preventLazyLoading() method.
  • НаукаНаука

Комментарии • 25

  • @mischl1
    @mischl1 3 года назад +29

    A bit of warning to those thinking that the "with" model property is the solution to all N+1 problems: enabling it on all models can quickly lead to recursion, and debugging nightmare. This aspect deserves significant consideration when planing out your architecture and use of the "with" property. For this reason I have avoided using the model property, and instead used with explicitly on eloquent queries. That also helps keep the payloads small, if you end up using the model in Livewire.

  • @MateusGalasso
    @MateusGalasso 3 года назад +6

    Greate video. We need more videos like that. More Laravel tips. Thx a lot

  • @luzaw4957
    @luzaw4957 2 года назад

    First time here and subscribe in a few seconds of video :) . Please do more tips and tricks. Thanks

  • @brainyworld2184
    @brainyworld2184 3 года назад

    Great and insightful

  • @mc-ty4br
    @mc-ty4br 3 года назад +2

    Neat indeed, thanks!
    One suggestion: maybe consider a slightly larger font next time (for both the browser as well as phpstorm)

  • @mohammadkhazaee9730
    @mohammadkhazaee9730 3 года назад

    Great video

  • @ahmed.shamim
    @ahmed.shamim 3 года назад +6

    You stated the argument that "we might forget to add eager loading using 'with' in eloquent query and that's why it's a good idea to use the 'with' attribute in the Model". But then it will cause more problems because every time it'll try to load all the relations defined in the model attribute. To solve it we need to use 'without' or 'withOnly' in the eloquent query. Aren't we back at where we started? Isn't it easy to forget about 'withOnly' and 'without' too? I believe that we are bloating the framework with many unnecessary features and trying to do everything inside the framework when these should be carefully done by the developers themselves.

    • @bethelosuagwu8021
      @bethelosuagwu8021 3 года назад

      I think you missed the whole point. The point is simple. 'with' is awesome but if you have phobia of it then Model::preventLazyLoading() is at hand. How is that possibly raining a complaint from you???

    • @ahmed.shamim
      @ahmed.shamim 3 года назад

      @@bethelosuagwu8021 You're saying that I've missed the whole point while you've missed the point of my comment. I didn't say anything regarding 'preventLazyLoading' and I think it's a good addition. Please read my comment again and try to understand what I'm complaining about.

    • @bethelosuagwu8021
      @bethelosuagwu8021 3 года назад

      @@ahmed.shamim Alright sorry. Your complaint is still misplaced because forgetting $with or with() leads to many queries to retrieve exact required data; while forgetting withOnly or without() leads to loading too much data but not necessarily running too much queries. So you are not back where you started since the first will most likely impact speed while the second could lead to 'out of memory'. So don't blame a framework for providing tools that allow users to choose what to compromise. I actually don't want to mention normalization where features provided by a framework globally nomalised among all framework users which also allows you to google your errors; this is not possible if the feature is implemented by you and used by yourself alone. Also if you have any time to look you will notice that features to the framework are thoroughly reviewed by the community comprising professionals; I would think twice about "bloating" branding given that these people probably value their work and more than half of the community would disagree with you.

    • @ahmed.shamim
      @ahmed.shamim 3 года назад +1

      @@bethelosuagwu8021 Don't consider me a 'Laravel hater', I myself am a full-time laravel developer and I love most of the things about Laravel. But that doesn't mean I have to defend everything regarding Laravel even if it seems like a bad decision. If you've been following the Laravel updates since a few major versions, you'll see that there were features added in Laravel and then later removed and sometimes even added again later. For example, the 'model' folder. These decision changes are part of the evolution of the framework and happened by the criticism from the community. If you don't criticize the bad decisions, you won't have the chance to make them right. And if you consider 'Laravel' the 'perfect framework', then you won't get the chance to improve it. So, even though I love working with Laravel, I still try to read and consider its criticisms with an open mind. 'Feature bloating in Laravel' is not only stated by the Laravel haters, rather a few more senior, experienced and knowledgeable PHP developers also complain about it. Yes, many people love to have most of the features integrated into the framework itself so that they don't have to do much work. But as you've said, probably 'almost half of the community' might 'disagree' with that. If you consider yourself a 'Laravel developer', you'll love to have everything in Laravel, but if you consider yourself a 'Software developer/engineer', you'll love the minimalism and simplicity in the framework and then plug the things you need. That's why I believe, having more features as 'plugin/component' is a good choice rather than having everything in the framework itself, because in that way you have the freedom to choose the things only you need.
      Regarding the 'with' property in the model, I'd still argue about it. For example, let's say I've added 3 relations in the $with property and I'm loading the model in 10 different places. That means in each of these 10 places, all of the 3 relations will be loaded, which will definitely reduce the performance in all of these places. What's the solution proposed? Adding the 'withOnly' in Model calls. That means I need to consider all of these 10 places to optimize by adding 'withOnly'. Also, if I add any more calls with the models, I have to add 'withOnly' there too. It's easy to forget that I'm loading relations behind the scene from the Model. Because it's not explicit in the Model call where you're using it. This is less readable, less visible and less efficient I think.
      But If I don't load any relations what might happen? Maybe from these 10 places, 3-4 places will lazyload relations and it'll hamper the performance. How would I measure it or when it'd be my concern? When I'll see performance degradation in those calls by monitoring the performance. How would I optimize it? By adding 'with' eager loading relations in those places. That means the other 6-7 places will not be my concern at all and even If I add more model calls, they won't bother me unless I monitor performance degradation in those places. Also, adding 'with' in the model call explicitly shows at that place, what I'm doing. More visibility, right?
      I just like this approach. You might have a different opinion, but that's fine. I'm not going to argue with you to adopt my POV. :)

    • @bethelosuagwu8021
      @bethelosuagwu8021 3 года назад

      @@ahmed.shamim No need to mention 'Laravel hater'. Many good points. But if we go back a step and realize that $with should only be used in those possibly rare cases where a relationship is ALWAYS required to be loaded then we will see that without() and withOnly() try to make the feature idiot-proof. I think we ought to read the doc. In the example you gave $with is misused probably because the programmer found about it in stackoverflow and did not open and see the firs line of the doc for it. See this week I did not read the doc and did this in Python: numpy.array([1.1,2.4]) and expected to get array of floats; totally my fault and not Numpy's. So I have to read the doc about features I did not create.

  • @abdianrizkyramadan1535
    @abdianrizkyramadan1535 3 года назад

    this is what just I need

  • @SowrenSen
    @SowrenSen 3 года назад +1

    Oh this is cool 😎

    • @themsaid
      @themsaid 3 года назад +1

      Glad you liked it :)

  • @AmeerHamza-cy6km
    @AmeerHamza-cy6km 2 года назад

    Thanks

  • @NathanBudd
    @NathanBudd 3 года назад

    This is cool. I wonder if you could automaticlly add the eager load by default when it is omitted?

    • @caiokawasaki2696
      @caiokawasaki2696 3 года назад +1

      Yes u can, just add $with = [] inside the model

  • @LaravelLover
    @LaravelLover 2 года назад

    Cheers

  • @marthasteve2274
    @marthasteve2274 3 года назад

    Hey Bro.... 1 help needed
    Awesome video. Just 1 more information I need for this,
    If i do use relation, I don't want to pull all columns from my 2nd table. How can I do it ? I hope you understood my question. Please do reply

    • @gtdmg489
      @gtdmg489 2 года назад +2

      Add list of column names to be included after your relation name in with.
      Product::with('properties:id,color')->get();

  • @Peter-ue4iz
    @Peter-ue4iz 3 года назад

    thats great but can you enable comments on your laravel vapor videos on this channel? why have you disabled the comments anyway?

    • @themsaid
      @themsaid 3 года назад

      Better contact Vapor support for any product concerns.

  • @twiggy99
    @twiggy99 3 года назад

    Why wouldn't eloquent use a join here and do it in one query?

  • @EL_PANDA_742
    @EL_PANDA_742 2 года назад

    Is this channel yours or you have other personal channel?!