-
-
Notifications
You must be signed in to change notification settings - Fork 101
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix: Prevent additional query when updating new graphs (faster inserts) #146
base: develop
Are you sure you want to change the base?
Conversation
@mk1024 - Thanks! We have incorporated your changes into our private code base. |
After this fix, on inserting of new entities, the associated entities are still being loaded again before saving the graph. The code where the loading happens is located here: Does this fix actually work? |
@cryo75 - If your entities have int/long primary keys and if you set |
I have the following:
` In my particular scenario, the associated entities in the Dto classes are the actual entities themselves. I do no expose the foreign keys. So, in the above, when inserting a new AddressModel, the model will only have a value for PostCodeModel. On saving I do:
But GraphDiff loads all the associated entites before saving, which, in my case, is unnecessary. Is there a way to trim down the loading of associated models before inserts/updates? (However, note that the returned model must have the actual foreign keys set after saving). |
@cryo75 - I think that not exposing the fk property (PostCodeModelId) is causing this issue. If PostCodeModel should not be updated/inserted with AddressModel anyway, you could just set PostCodeModelId and leave PostCodeModel empty when inserting. Depending on your model and configuration, this should do the trick. |
Preferably I would need a mixture so that GraphDiff:
As for OwnedCollections, the default will still apply. Is this possible? |
I'm using GraphDiff in a few projects that perform a lot of batch updates and inserts. Here are my optimizations that made it about 15-20x faster in my use cases. All tests in GraphDiff.Tests and in my own projects run fine. Perhaps Brent or Andreas can have a look at my changes.
Inserting new entities
When updating new graphs (insert) GraphDiff tries to load the persisted graph, which always returns null and requires a lot of unneccessary work (predicate expression, include strings, actual query to db). If an entity is new and not persisted yet, you should not try to load it from the database.
This optimization is optional for simple int and long primary keys (
GraphDiffConfiguration
) and is automatically ignored in other scenarios (string/guid/composite/etc).Updating of collections
When updating many entities of the same type you have to call UpdateGraph in a loop. This results in a lot of queries from
QueryLoader
and extremely slows down large batch updates. As proposed by DixonD-git (Issue https://github.com/refactorthis/GraphDiff/issues/127), loading of many entities can be done in a single query to increase performance.The performance boost was quite a surprise (15-20x on my local machine). I only had to change internal interfaces and classes, while the public interface (
DbContextExtensions
) did not change. Composite keys create predicates like(KeyA='a1' AND KeyB='b1') OR (KeyA='a2' AND KeyB='b2') OR ...
and single int keys are translated to...Key in (1,2,3,4,5...)
.