Last month I posted PAGELATCH Contention on 2:1:103. It described a troubleshooting experience I had. I was troubleshooting a performance problem that was felt when applications issued very frequent ad hoc queries that used Table Valued Parameters (TVPs).
I’ve recently learned some extra things from the SQL Server team at Microsoft that I wanted to pass on. So this post acts as a kind of update to that one.
One thing I did was to come up with an application that reproduces the contention on 2:1:103 in the same way as production. I share that here now.
What this reproduction does is launch fifty processes. Each process uses multiple threads to hit a db server with an ad hoc query that uses a TVP. For the curious here it is: Download AdHocTVPContention.zip and then open readme.txt. This reproduction is a mashup of
- A simple batch script which launches an executable 50 times at once. A technique I gleaned from Paul Randal in a demo of his.
- A multi-threaded executable which sends queries asynchronously. A framework I first developed in a post I wrote on concurrency.
- The ad hoc TVP query itself. It was a bit of a modification of my example at Table Valued Parameters, A Short Complete Example. The only difference is that the command is a query instead of a stored procedure.
What I’ve Learned Since Then
The Microsoft team helped me understand a few things. The main thing is that the particular version of SQL Server (including service pack level) matters a lot:
SQL Server 2005 and Earlier
TVPs weren’t supported then. (This post isn’t for you).
SQL Server 2008 and R2
In my earlier post, I dismissed a fix provided by Microsoft. Fix: Poor performance in SQL Server 2008 R2 when table-valued functions use many table variables. At the time, I dismissed it for a number of reasons:
- The workaround listed on that kb article page did not help us.
- The symptoms that were described at that issue did not match my own scenario (i.e. I wasn’t using table-valued functions).
- The title mentioned R2 and I thought (mistakenly) that this fix was not applicable to SQL Server 2008. (Update April 5, 2013: The fix used to be available as a hotfix for 2008 SP3, but as of March 2013, this fix is now included in a cumulative update. Upgrade to SP3 CU10 if you’re using 2008 and want this fix. Microsoft has also updated the title of the fix to mention 2008)
Microsoft helped me learn that although the symptoms in that fix differ from mine, the improvement in that fix involves a change to code that also improves my scenario. So with the fix applied, on my test environment, I saw that SQL Server could handle at least 6 times the volume of ad hoc queries than it could before (your mileage may vary).
SQL Server 2012
But there’s one other thing I noticed. When I ran the reproduction on a SQL Server 2012 environment, the process just flew through the workload! Temp table creation was no longer a bottleneck; there was no more contention on temp table creation. The Microsoft Engineer I worked with noticed this too and eventually it prompted a CSS blog entry. You can read all about this 2012 performance improvement at Temp table caching improvement for table valued parameters in SQL Server 2012
Partner vs MVP
I’m very lucky to have many investigation options available to me when I’m digging into a particular quirk of SQL Server behaviour. There’s the public options like #sqlhelp or dba.stackexchange or Microsoft support. And for me there’s some private options like the MVP mailing list. But this month, I feel lucky to work as a Microsoft partner. It’s through that connection that I learned so much.
Too Long; Didn’t Read
If you’re experiencing 2:1:103 contention because of too frequent ad hoc TVP queries then:
- http://support.microsoft.com/kb/2566163 will help you out of a jam and
- SQL Server 2012 will squash that issue for good.