Skip to content
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

[Performance] NHibernate is evaluating all properties during Execution #3534

Open
rcocks-hl opened this issue Apr 26, 2024 · 4 comments
Open

Comments

@rcocks-hl
Copy link

Hi,

I've run into a significant performance problem. Profiling is showing a large amount of time spent running a fairly simple DELETE query:

The Query definition is:

DELETE FROM [SchemaName].[TableName]  WHERE ParentId=:parentId AND ChildId=:childId AND Name=:name

But it's accessing every property on the owning class.

There's an expensive calculated property on the class (Description) but it's not one that should be needed for this query.

Some other experimentation suggested it was perhaps caused by calling Lock(object, LockMode.None), but it's not clear how that would cause this property to be read. Elsewhere in the same transaction it is updating a different property on this object.

dotTrace suggests it's from AutoFlush being triggered, and inside FlushEverythingToExecutions all properties are read.

Is there a way to:

  1. Avoid auto-flush
  2. Prevent the flush reading all properties when it does so.

Unfortunately I've struggled to reproduce this with a simpler example.

@oskarb
Copy link
Member

oskarb commented Apr 26, 2024

Avoid auto-flush

FlushMode is a setting on the session. Some are more dangerous than others (in that it puts greater responsibility on the application developer to flush when needed, which is easy in some cases and challenging in others (e.g. if different parts of the code might dynamically share a transaction).

Prevent the flush reading all properties when it does so.

As the point of flushing is to find all changes that need to be sent to the database, I think the idea of doing that without reading the properties is inherently impossible. At the moment I'm a little foggy on what alternatives you have to treat just Description differently. Consider looking in the reference manual's section on mapping and performance.

You might of course also consider using a method instead of a property if it's expensive, or not map that property to the database, or cache the calculated value. But I'm a bit confused... you say "calculated". But if it's calculated, why is it mapped to the database?

@rcocks-hl
Copy link
Author

Hi @oskarb , thanks for the reply.

The reason it's being persisted is because it's a subclass where on the base class the property is persisted as a string, but in this subclass it's calculated instead.

I can't see a way of preventing it being mapped in the subclass, but if that is possible then that'd work fine as a solution.

@hazzik
Copy link
Member

hazzik commented Jul 9, 2024

@rcocks-hl can you show how you run the query?

@rcocks-hl
Copy link
Author

Hi @hazzik - I'm not sure I can get my employers' permission to share the exact code, but I'll try to produce a minimal reproduction.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants