6

This isn't a question of "which is the fastest ORM", nor is it a question on "how to write good code with ORMs". This is the other side: the code's been written, it's gone live, several thousand users are hitting the application, but there's a perceived overall performance problem. A SQL Profiler trace can only be ran for a short amount of time: 5 mins gives several hundred thousand results.

The question is simply this: having used SQL Profiler to narrow down a number of slow queries (duration greater than a given amount of time), what techniques and solutions exist for tracing these SQL queries back into the problematic component? A releated question is that if a specific area is slow, how can we identify the SQL that this area is executing so it can be suitably filtered in SQL Profiler?

The background to this is that we have a rather large application with a fairly complex table structure, and is currently based around data-access via stored procedures. If a SQL performance problem arises, it's usually case of pulling out SQL profiler, find out if there's anything slow (filter by duration) or if a the area being complained about is slow (filter by stored procedure), and tune the stored procedures (or the schema - through indexing).

Now there's a push to move our code over from a mostly-sproc solution to a mostly-ORM solution, however the big push against the move is how performance problems, if they arise, can be traced back to problematic code. I've read around and it seems that more often than not, it may involve third-party tools (ORM tracing utilities like NHProf or .NET tracing utils like dottrace) that we'd need to install on the server. Now whether additional tools can be installed on a live environment is another question, so if things like this can be performed without additional tools, then that may be a bonus.

I'm mostly interested in solutions with SQL Server 2008, but it's probably generic enough for any RDBMS. As far as the ORM tech, on this I have no specific focus as nothing's currently in use, so be interested to hear how techniques differ (or are common) twixt nHibernate, fluent-nhibernate and Entity Framework. Other ORMs are welcome though if they offer something else :-)

I've read through How to find and fix performance problems (...), and I think the issue is simply the section on there that says "isolate". A problem that is easily reproducible only on a live system is going to be difficult to isolate. The figures I quoted in para 2 are figures the types of volumes that we can get from a profile as well...

If you have real-world experience of ORM tracing on live, so much the better :-)

Update, 2016-10-21: Just for completeness, we eventually solved this for NHibernate by writing code, and overriding NHibernate methods. Full details in this other SO question I asked: NHibernate and Interceptors - measuring SQL round trip times. I expect this will be a similar approach for many different ORMs.

Community
  • 1
  • 1
Chris J
  • 30,688
  • 6
  • 69
  • 111
  • Are you familiar already with the various DMVs and reports that show top query by duration, CPU, IO etc. based on execution plan stats rather than profiling? Also what version of SQL Server? If 2008 there is the management data warehouse that may help (though I guess with non parameterised queries issued by an ORM you may end up with lots of similar queries and plans making aggregating the results difficult) – Martin Smith Jan 26 '11 at 17:24
  • Interesting question, I look forward to learning something about this subject since I don't have an answer for you. – HLGEM Jan 26 '11 at 17:47
  • @Martin -- sorry, 2008 (question edited). Now you mention the DMVs, that does ring bells, will investigate. The app at the moment is based on SQL 2000, but the next version's being elevated to 2008. Not *too* bothered about 2000 solutions. Though once we have the query, how do we trace that backwards to the module that's causing the problem via the ORM layer? – Chris J Jan 26 '11 at 18:27
  • @Chris - RE: Tracing backwards I don't think they would help. They would only help in identifying queries to focus on without needing to involve profiler. – Martin Smith Jan 26 '11 at 18:30
  • @Martin ... That's the problem -- if the only way to change the query is to change the ORM code, I'm stuck :-) Thanks for the reminder there though; it'll certainly save some headaches. – Chris J Jan 26 '11 at 18:33
  • >> how can we identify the SQL that this area is executing so it can be suitably filtered in SQL Profiler? >> If you are asking if it is possible to create filters for duration, it is possible in sql profiler, do I understand you right? – Danil Jan 26 '11 at 18:39
  • @Danil ... No -- I'm asking once I've identified the SQL, what methods or tools exist to trace it back into the ORM component that made the call in the first place? I have no problem using SQL profiler -- it's a powerful tool in my SQL arsenal. – Chris J Jan 26 '11 at 18:57

2 Answers2

2

There exists profilers for ORM tools, like UberProf. It finds out which SQL statements that are generated by the ORM can be problematic.

Like the select n+1 problem, for instance. These kind of tools might give you an indication of which ORM query statements result in poor SQL code, and perhaps even how you could improve them.

Frederik Gheysels
  • 56,135
  • 11
  • 101
  • 154
  • How good are tools like this in a live environment which can be very heavily loaded (see volumes stated in the question)? And I'm assuming that with these, you can find the code that's using the ORM in this way? Also, if we've got the application deployed over (say) half a dozen application servers, it's possible we'd have to trace over half a dozen application servers (although we could trace on one and hope the issue appears there, it then doesn't give a full picture of what's happening on the database -- so use in conjunction with tools like SQL Profiler?) – Chris J Jan 27 '11 at 09:07
0

We had a Java/Hibernate app with issues, so we used SET CONTEXT_INFO with a different value. If we saw, say, 0x14 on the same SPID just before a WTF query, we could narrow it to module x.

Not being a Java guy, I don't know exactly what they did, and of course it may not apply to .net. IIRC you have to be careful about when connections are opened/closed

We could also control the client load at this time so we didn't have too much superfluous traffic.

YMMV of course, but it may be useful

I just found these which could be useful too

Community
  • 1
  • 1
gbn
  • 422,506
  • 82
  • 585
  • 676
  • Interesting approach; I have wondered if there was a way of "watermarking" SQL statements... may be one to look into further. – Chris J Jan 27 '11 at 09:08