Strange(?) performance problems

  • I am debugging an NHibernate generated SQL_query for performance problem and came up with something strange.

    The query is a SELECT statement that reads from a view. I've tracked the problem to this part of the query:

    AND (myView.A LIKE (@p7+'%') OR myView.B=@p8 OR myView.C=@p9)

    If I run the query with only condition at a time, no matter which one, the query goes very fast, almost no database-reads. However, when all three are used (or two), things starts to crawl and database reads goes beyond 2,000,000.

    Anyone got any ideas what might be going on?

  • Have a look at https://www.sommarskog.se/query-plan-mysteries.html

    Slow in app / fast in ssms symptom

    Like when debugging you may have setted the variable to literals which sql server can sniff for a better plan

  • The query is slow (when using all three conditions) no matter what I use, SSMS or app.

  • can you give us the actual explain plan with both the 3 conditions and just 1 condition - as well as the definition of the view.

    likely this is joining multiple tables and in order to satisfy the 3 conditions it needs to read a significant part of the underlying tables before filter can be applied.

    likely your solution here is do do the 3 queries as a union (to remove dups, but be aware this can lead to removal of needed rows) with 1 condition each

  • I can't share the executionplans (without massive censoring) since it belongs to the place I work sadly.

    It would be quite easy try running the query 3 times but since this is NHibernate compiled SQL and not a stored procedure it's not that simple. :/

  • use PlanExplorer to scramble the names - https://www.solarwinds.com/free-tools/plan-explorer

    that will replace any object name (db, table, column) with object1, object2 and so on - but it will leave intact the remaining info that is what we need.

  • Of course, splitting the query and using UNION ALL to put it all together may be an option too.

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution πŸ˜€

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • No I can't use UNION since this is NHibernate generated.. I really prefer good old hand-coded SQL though.. πŸ™‚

    I made a simpler query than the actual one but the problem is still there.

    SELECT Object1.Column1, Object2.Column1
    FROM Object3 Object1
    LEFT JOIN Object4 Object2 on Object2.Column1 = Object1.Column2
    WHERE (Object2.Column3 = Variable1 OR Object1.Column4=Variable2) AND Object1.Column5=Variable3
    AND Object1.Column6 = ?
    ORDER BY Object1.Column7 ASC
    OFFSET Variable4 ROWS FETCH FIRST Variable5 ROWS ONLY

    The problem is:

    WHERE (Object2.Column3 = Variable1 OR Object1.Column4=Variable2)

    If both of these two are active, it's causing massive amounts of database reads. If only one of them, anyone, is active, things goes very fast.

    Executionplan is attached if you're curious..

    Attachments:
    You must be logged in to view attached files.
  • I asked Copilot how to overrule an Nhibernate generated query:

    To overrule or customize an NHibernate-generated query, you can use native SQL queries or HQL (Hibernate Query Language). Here are a few methods:

    Using Native SQL Queries:

    You can directly write SQL queries using the ISQLQuery interface. This allows you to leverage database-specific features and have more control over the query.

    var sqlQuery = session.CreateSQLQuery("SELECT * FROM YourTable WHERE YourCondition");

    var result = sqlQuery.List();

    This method is useful for complex queries or when you need to use specific SQL features1.

    Using HQL (Hibernate Query Language):

    HQL is similar to SQL but operates on the object model rather than the database model. You can write HQL queries to fetch data in a more object-oriented way.

    var hqlQuery = session.CreateQuery("FROM YourEntity WHERE YourCondition");

    var result = hqlQuery.List();

    HQL provides a more abstract way to interact with the database, making it easier to work with entities2.

    Using Criteria API:

    The Criteria API allows you to build queries programmatically. This can be useful for dynamic queries where the criteria might change based on user input or other factors.

    var criteria = session.CreateCriteria<YourEntity>()

    .Add(Restrictions.Eq("YourProperty", YourValue));

    var result = criteria.List();

    This method is flexible and allows for complex query building2.

    Overriding Fetch Strategies:

    You can override the default fetch strategies for specific transactions using left join fetch in HQL. This can help optimize performance by reducing the number of SQL queries generated.

    var hqlQuery = session.CreateQuery("FROM YourEntity e LEFT JOIN FETCH e.YourAssociation WHERE e.YourCondition");

    var result = hqlQuery.List();

    This approach ensures that associations are fetched eagerly in the initial query3.

    These methods give you control over the queries generated by NHibernate, allowing you to optimize performance and tailor the queries to your specific needs.

    Is there a particular scenario or query you’re working on that you’d like more detailed help with?

    Β 

    Document your exception in Nhibernate as well !! (Why did you use it, what are the gains )

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution πŸ˜€

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • There's no way for me to override the NHibernate stuff in the solution I'm working in. It's way too complex and even if I manage to do it, people will have strong opinions why I'm going for native SQL.

  • That are indeed valid arguments to take into account.

    Our world is mainly about being able to cooperate !

    Johan

    Learn to play, play to learn !

    Dont drive faster than your guardian angel can fly ...
    but keeping both feet on the ground wont get you anywhere :w00t:

    - How to post Performance Problems
    - How to post data/code to get the best help[/url]

    - How to prevent a sore throat after hours of presenting ppt

    press F1 for solution, press shift+F1 for urgent solution πŸ˜€

    Need a bit of Powershell? How about this

    Who am I ? Sometimes this is me but most of the time this is me

  • Might have discovered a piece of the puzzle..

    When problematic query looks like this.. WHERE param=@p1 it might run fine if I add a relevant index in SSMS, but if I hardcode it instead, WHERE param='p1' (same value as @p1) I get poor performance (just like the app).

  • That's odd, I would expect better performance because it can sniff the hardcoded value and use it for the query plan.

    Perhaps the hardcoded value is not the same datatype as the database causing a table scan?

  • They are all NVARCHAR's so that shouldn't be the problem.

  • frederico_fonseca wrote:

    use PlanExplorer to scramble the names - https://www.solarwinds.com/free-tools/plan-explorer

    that will replace any object name (db, table, column) with object1, object2 and so on - but it will leave intact the remaining info that is what we need.

    can you do as I mentioned above. nothing on the resulting file will identify db, table or even column names, neither any parameter supplied.

Viewing 15 posts - 1 through 15 (of 20 total)

You must be logged in to reply to this topic. Login to reply