3

SQL2008 R2 で Change Tracking を使用していますが、バッチで影響を受ける行を特定しようとすると、非常に奇妙な動作が見られます。パラメータ値を使用すると、ストアド プロシージャの実行に約 30 秒かかりますが、リテラル値を呼び出しに入れると、 CHANGETABLE 関数に対しては、<1 秒で返されます。

次の呼び出しには約 30 秒かかります。

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
)

ただし、以下のように CHANGETABLE 行を変更すると、最大 1 秒に短縮されます。

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

SP1 を実行しているので、SQL2008 CU4 でリリースされた、CHANGETABLE が遅いというパッチが修正されたと思います (http://support.microsoft.com/kb/2276330)。

途方に暮れていますが、パラメーターをリテラル値に変更すると、なぜそれほど違いが生じるのでしょうか?

4

1 に答える 1

4

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

于 2012-01-19T21:32:25.583 に答える