Question

I'm using Change Tracking in SQL2008 R2 and seeing a very odd behaviour when trying to determine rows affected in a batch, a stored proc takes ~30 seconds to run when using a parameter value, but when I put the literal values in the call to the CHANGETABLE function it returns in <1s.

A call to the following takes ~30s:

DECLARE  @sync_last_received_anchor BigInt;
DECLARE  @sync_new_received_anchor BigInt;

SET @sync_last_received_anchor = 272361;
SET @sync_new_received_anchor = 273361;

SELECT [Customer].[CustomerID]
FROM dbo.tblCustomer AS [Customer] WITH (NOLOCK) 
    INNER JOIN CHANGETABLE(CHANGES [REDACTED].[dbo].[tblCustomer], @sync_last_received_anchor) AS [theChangeTable] 
    ON [theChangeTable].[CustomerID] = [Customer].[CustomerID]
WHERE ([theChangeTable].[SYS_CHANGE_OPERATION] = 'U' 
    AND [theChangeTable].[SYS_CHANGE_VERSION] <= @sync_new_received_anchor
)

However changing the CHANGETABLE line, as below, reduces it to ~1s.

    INNER JOIN CHANGETABLE(CHANGES [REDACTED].[dbo].[tblCustomer], 272361) AS [theChangeTable] 

As we're running SP1 I presume the patch released in SQL2008 CU4 for CHANGETABLE being slow has been fixed (http://support.microsoft.com/kb/2276330).

I'm at a loss though why changing a parameter to a literal value would make so much difference?

Was it helpful?

Solution

It is likely that the stored procedure is doing parameter sniffing - i.e. it thinks the values you supplied are a good match for a plan it has already cached and it it isn't a good match at all.

There are multiple articles on how to approach this issue, one you can test and try on a DEV environment would be this:

http://blogs.msdn.com/b/axperf/archive/2010/05/07/important-sql-server-change-parameter-sniffing-and-plan-caching.aspx

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top