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