The INSANE Performance Boost Of CQRS Read Models

แชร์
ฝัง
  • เผยแพร่เมื่อ 6 ก.พ. 2025

ความคิดเห็น • 66

  • @MilanJovanovicTech
    @MilanJovanovicTech  ปีที่แล้ว +1

    Want to master Clean Architecture? Go here: bit.ly/3PupkOJ
    Want to unlock Modular Monoliths? Go here: bit.ly/3SXlzSt

  • @theundaddy8037
    @theundaddy8037 ปีที่แล้ว +4

    You are definitely one of the best at explaining microservice related concepts. Keep up the good work!

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      I've a nice video coming out on Friday about Materialized views :)

  • @ryanseipp6944
    @ryanseipp6944 ปีที่แล้ว +17

    Now you need to keep this summary up to date with every change you make to the parent Order, just to pre-calculate a sum. If you're already violating normalization, you might as well have the sum in your domain model to get updated automatically on LineItem change and just query the domain model directly, saving yourself the trouble of keeping two disjoint entities in sync.
    You might save yourself some blowback if you save the juicy "performance inside" title for the video with the benchmarks.

  • @sergiom.954
    @sergiom.954 ปีที่แล้ว +2

    Thanks for the video Milan!👏👏
    I am very interested in next video about eventual consistency.

  • @mreshboboyev
    @mreshboboyev 2 หลายเดือนก่อน

    This is awesome and useful content

  • @10199able
    @10199able ปีที่แล้ว +13

    Where are the benchmarks for this insanity?

  • @kodindoyannick5328
    @kodindoyannick5328 11 หลายเดือนก่อน

    Thank you so much Milan.

  • @rustamhajiyev
    @rustamhajiyev ปีที่แล้ว +2

    Thanks! Please show us a couple of approaches when dealing with eventual consistency and stale data in the next episode ;)

  • @adrianvdh
    @adrianvdh 6 หลายเดือนก่อน

    How can you project a new read model from historic events? Are the only options are to replay events from an event store or data migrations?

    • @MilanJovanovicTech
      @MilanJovanovicTech  6 หลายเดือนก่อน

      Replay all of them, or replay them from a specific snapshot

  • @nicolasundiano8406
    @nicolasundiano8406 ปีที่แล้ว +1

    Hi Milan, i really like this approach for this example: I have 3 aggregate roots User, Role and Permission. They no have navigation properties because the are separate aggregates so they are related only with the Id. Use has RoleId, Role has a list of PermissionIds and Permission has a list of RoleIds, so with EF Core we know that querying a Role with the Permission and it properties is very difficult. So i want to apply your approach of creating ReadModels and the tables of them. Do you are still convinced of this approach? Or now you have a better idea?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      Oh yeah, that's a nice use case for something like this. You can also read the values the 'traditional' way via EF - and store them in a cache

  • @balazs.hideghety
    @balazs.hideghety ปีที่แล้ว +3

    First of all, the great performance boost is due to redundant data we create (not ideal). Considering CQRS using views, indexes, AsNoTracking can yield similar performance results, without creating redundant data (which if we don't handle with care, can result in wrong/corrupted data being returned, compromising entire domain logic).

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      Is redundant data always bad? I don't think so.

    • @balazs.hideghety
      @balazs.hideghety ปีที่แล้ว

      ​@@MilanJovanovicTechdepends, also on the way how youvet to it. But my issue is that the huge perf boost wasn't due to well crafted CQRS but rather due to redundant data. Otherwise 👍

  • @maxencemartin6498
    @maxencemartin6498 5 หลายเดือนก่อน

    Hi Milan , thank you for this video. I'm looking for a video of you in wich you are explaining how you create OrderSummaries (Read model) asynchronously with background process by an event (bus). I think i've already seen it but i can't find it. Thank in advance.

    • @MilanJovanovicTech
      @MilanJovanovicTech  5 หลายเดือนก่อน +1

      This one: th-cam.com/video/2ZNMlx44gKQ/w-d-xo.html

  • @donnyroufs551
    @donnyroufs551 ปีที่แล้ว +4

    Im confused on why you save order summaries, why not have a custom view which becomes your readmodel?

    • @joaomachado9105
      @joaomachado9105 ปีที่แล้ว

      had the exact same question xD but now that i think of it, it kinda makes sense, because with views if you have "calculations/joins" to get some collumns that gets processed when you make a query to the database, but if you insert the calculated value on the table yourself, you only need to process that during inserts/updates, and whenever you query you are just reading from a table without joins/computations, but it just seems to add a lot of overhead to your code and can lead to inconsistent data if your not carefull

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +2

      A view isn't persisted. This is. And imagine a more complex data model, things should make sense.

  • @barr5221
    @barr5221 ปีที่แล้ว +4

    Did you try to use database view instead? Duplication of data is kind of nightmare, when you have to perform migration of data.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      Agreed, but views are still just a SQL query executed at runtime

    • @andersonhansen9542
      @andersonhansen9542 ปีที่แล้ว +1

      In this case, I think a materialized view is an option because it is a physical table that is created from the query.

  • @mirzacupina-ll4lx
    @mirzacupina-ll4lx ปีที่แล้ว +1

    Milan, have you tried to achieve this with pre-computed columns? Would they be suitable for this particular case, but not so much for more complex models?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      It would be fine if the model was simple. But I should have used a more complex model here with many joins, so people would understand. I'll correct this mistake in a future video :)

  • @datadigger2432
    @datadigger2432 ปีที่แล้ว

    Hello Milan,
    why do you not wrap orders and orderSummaries with Db transaction ?

  • @weneedlittlepatience
    @weneedlittlepatience 10 หลายเดือนก่อน +2

    giga bro's on a whole different level 🔥

  • @GuerreroVicttor
    @GuerreroVicttor ปีที่แล้ว +1

    hi Milan, do you recommend use vscode for c# projects? do you use vscode? greetings!!! great video!!!

  • @winchester2581
    @winchester2581 ปีที่แล้ว +2

    Literally started watching the video 30 seconds after publication. Great work!

  • @krccmsitp2884
    @krccmsitp2884 ปีที่แล้ว +2

    Nice as always, however, I am somehow missing a performance comparison here.

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      Lesson learned! I'll show a perf. benchmark for the async Read model video

    • @krccmsitp2884
      @krccmsitp2884 ปีที่แล้ว

      @@MilanJovanovicTech I'm looking forward to it 👍

  • @Masteroxify
    @Masteroxify ปีที่แล้ว +1

    What about sql indexes ? Can you compare those two options ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      What about them?

    • @Masteroxify
      @Masteroxify ปีที่แล้ว

      @@MilanJovanovicTech we can make index and indicate in and out parameters of SELECT, what increase performance of searching. So it seems to be very similar with solution you introduced.

  • @peterasamoah5489
    @peterasamoah5489 ปีที่แล้ว +1

    Hi Milan, what happens when you want to change the read model? Will this involve changing the schema or joining on other read model tables ? Doesn't this approach add a bit more complexity since the read models may evolve with time or as requirements change and each change will require a schema change ?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +3

      If you want to change the read model, then you'd have to recompute it again somehow. This is a bit difficult with this synchronous implementation. If we were processing events, it would be easier since we could replay the events.
      Yes, this adds a lot more complexity. I'll show an async + eventually persisted implementation next, along with a benchmark!

    • @lukaskuchta1010
      @lukaskuchta1010 ปีที่แล้ว

      Hi is this video with background creation of read models ready or we must waiting for realeas? Thanks for your work. And stay awsome!!! 😂😂

  • @empireofhearts
    @empireofhearts ปีที่แล้ว

    i was waiting for how total price is handled in the read model but never got there. Would you handle that when order is completed with another event?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      I'll tackle it in the async version, when I introduce more actions on LineItems

  • @krazaam6205
    @krazaam6205 ปีที่แล้ว +6

    "INSANE Performance" - no benchmarks. LOL

  • @waltavista
    @waltavista ปีที่แล้ว +1

    Interesting, but as others have pointed out, the video doesn't make as much sense without comparison. I would even go so far as to say that the approach has more disadvantages overall than advantages in terms of disadvantages (duplicate data, problems updating).

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว

      I'll add a benchmark in the async version of read models

  • @sametcekiny
    @sametcekiny ปีที่แล้ว +1

    Actually you shouldn't changed Order summary OrderId property name to Id cause of ıt is OrderSummary-OrderId not Order-Id

  • @jameshancock
    @jameshancock ปีที่แล้ว +1

    Why not use triggers or compiled views?

    • @MilanJovanovicTech
      @MilanJovanovicTech  ปีที่แล้ว +1

      Sure, if you want to move that into DB 🤷‍♂️

    • @jameshancock
      @jameshancock ปีที่แล้ว

      @@MilanJovanovicTech The thought is that it's lower level and automatic and you can't miss it, and it's also faster if done right.

    • @jameshancock
      @jameshancock ปีที่แล้ว

      @@saymyname148 not at all. Just lost developers don’t understand them.
      And if you don’t use them then a direct database change ignores everything you’re doing.

  • @techpc5453
    @techpc5453 ปีที่แล้ว +1