As a DBA, I'm involved on an almost daily basis troubleshooting 'SQL Server' performance issues. Often, this troubleshooting soon veers away from a 'its a SQL Server issue' to instead become a wider application/database design/coding issue.
One common perception with SQL Server is that deadlocking is an application design issue - and is fixed by recoding... I see this reinforced by MCP-type questions/scenarios where the answer to prevent deadlocking is simply to change the order in code in which tables are accessed....
Whilst this is correct, I do think this has led to a situation where many 'operational' or 'production support' DBAs, when faced with a deadlock, are happy to throw the issue over to developers without analysing the issue further....
A couple of 'war stories' on deadlocks which I think are interesting :-
Case One , I had an issue recently on a third-party application that I support on SQL 2008.
This particular third-party application has an unusual support agreement where the customer is allowed to change the index design on the third-party provided database.
However, we are not allowed to alter application code or modify table structure..
This third-party application is also known to encounter occasional deadlocks – indeed, I have documentation from the vendor that up to 50 deadlocks per day is not unusual !
So, as a DBA I have to support an application which in my opinion has too many deadlocks - but, I cannot influence the design of the tables or stored procedures for the application.
This should be the classic - blame the third-party developers scenario, and hope this issue gets addressed in a future application release - ie we could wait years for this to be resolved and implemented in our production environment...
But, as DBAs can change the index layout, is there anything I could do still to reduce the deadlocks in the application ?
I initially used SQL traceflag 1222 to write deadlock detection output to the SQL Errorlog – using this I was able to identify one table heavily involved in the deadlocks.
When I examined the table definition, I was surprised to see it was a heap – ie no clustered index existed on the table.
Using SQL profiler to see locking behaviour and plan for the query involved in the deadlock, I was able to confirm a table scan was being performed.
By creating an appropriate clustered index - it was possible to produce a more efficient plan and locking behaviour.
So, less locks, held for less time = less possibility of deadlocks.
I'm still unhappy about the overall number of deadlocks on this system - but that's something to be discussed further with the vendor.
Case Two, a system which hadn't changed for months suddenly started seeing deadlocks on a regular basis. I love the 'nothing's changed' scenario, as it gives me the opportunity to appear wise and say 'nothings changed on this system, except the data'..
This particular deadlock occurred on a table which had been growing rapidly. By using DBCC SHOW_STATISTICS - the DBA team were able to see that the deadlocks seemed to be occurring shortly after auto-update stats had regenerated the table statistics using it's default sampling behaviour.
As a quick fix, we were able to schedule a nightly UPDATE STATISTICS WITH FULLSCAN on the table involved in the deadlock - thus, greatly reducing the potential for stats to be updated via auto_update_stats, consequently reducing the potential for a bad plan to be generated based on an unrepresentative sample of the data. This reduced the possibility of a deadlock occurring.
Not a perfect solution by any means, but quick, easy to implement, and needed no application code changes.
This fix gave us some 'breathing space' to properly fix the code during the next scheduled application release.
The moral of this post - don't dismiss deadlocks as issues that can only be fixed by developers...