Sql-Server
如何只清除目前會話中的查詢計劃?
我正在一個非常繁忙的伺服器上調整查詢,我不想清除記憶體,使用
DBCC FREEPROCCACHE
;我知道它至少會導致 CPU 峰值,在這種情況下我不想要它。
-- Example 2 (Ballpeen hammer) -- Remove all elements from the plan cache for one database -- Get DBID from one database name first DECLARE @intDBID INT; SET @intDBID = (SELECT [dbid] FROM master.dbo.sysdatabases WHERE name = 'AdventureWorks'); -- Flush the procedure cache for one database only DBCC FLUSHPROCINDB (@intDBID);
我想做這樣的事情:
-- Example 3 (Scalpel) -- Remove one plan from the cache -- Get the plan handle for a cached plan SELECT cp.plan_handle, st.[text] FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st WHERE [text] LIKE N'%/* GetOnlineSearchResultsMonday %'; -- Remove the specific plan from the cache using the plan handle DBCC FREEPROCCACHE (0x05000800F7BA926C40C15055070000000000000000000000);
有什麼方法可以找到我正在處理的查詢,或者至少在記憶體中找到我自己的會話?
我正在調整以下查詢:
checkpoint set statistics io on set statistics time on SET NOCOUNT ON; DECLARE @OrderStartDate DATETIME DECLARE @OrderEndDate DATETIME SELECT @OrderStartDate = '27-FEB-2016' SELECT @OrderEndDate = '28-FEB-2016' SELECT op.lngPaymentID ,op.strBxOrderNo ,op.sintPaymentTypeID ,op.strCurrencyCode ,op.strBCCurrencyCode ,op.decPaymentAmount ,op.decBCPaymentAmount ,ap.strAccountCode ,o.sintMarketID ,o.sintOrderChannelID ,o.sintOrderTypeID ,CASE WHEN opgv.lngpaymentID IS NULL THEN NULL -- Not a Voucher = Null WHEN gvp.strIssuedBxOrderNo IS NULL THEN 0 ELSE 1 END AS [IsPromoVoucher] -- Is a Voucher - check type ,o.sdtmOrdCreated FROM tablebackups.dbo.tblBOrderItemOrderComplete com INNER JOIN tablebackups.dbo.tblBOrderPayment op on op.strBxOrderNo = com.strBxOrderNo INNER JOIN tablebackups.dbo.tblBOrder o ON op.strBxOrderNo = o.strBxOrderNo INNER JOIN tablebackups.dbo.tblBOrderItem as oi on com.strBxOrderNo = oi.strBxOrderNo AND com.sintOrderSeqNo = oi.sintOrderSeqNo INNER JOIN tablebackups.dbo.tblBAccountParticipant ap ON o.lngAccountParticipantID = ap.lngParticipantID LEFT OUTER JOIN tablebackups.dbo.tblBOrderPaymentGiftVoucher opgv ON op.lngPaymentID = opgv.lngPaymentID LEFT OUTER JOIN tablebackups.dbo.tblBGiftVoucher gv ON opgv.strVoucherNumber = gv.strVoucherNumber LEFT OUTER JOIN tablebackups.dbo.tblBGiftVoucherPromotion gvp ON gvp.strIssuedBxOrderNo = gv.strIssuedBxOrderNo WHERE com.LoadDate >= @OrderStartDate AND com.LoadDate < @OrderEndDate AND o.sdtmOrdCreated >= @OrderStartDate AND oi.decCatItemPrice > 0 set statistics io off set statistics time off
Marcello,您的問題似乎已經有了答案,儘管稍作修改。
查詢:
SELECT cp.plan_handle, st.[text] FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st WHERE [text] LIKE N'%/* GetOnlineSearchResultsMonday %';
包含術語
'%/* GetOnlineSearchResultsMondy %'
,這是一個萬用字元搜尋,用於定位要從記憶體中刪除的特定計劃。如果您使用包含在您嘗試調整的查詢中的搜尋詞執行它,它應該返回一個計劃句柄,然後可以使用DBCC FREEPROCCACHE
:-- Remove the specific plan from the cache using the plan handle DBCC FREEPROCCACHE (0x05000800F7BA926C40C15055070000000000000000000000);
我建議也許使用以下方法來辨識查詢:
SELECT cp.plan_handle, st.[text] FROM sys.dm_exec_cached_plans AS cp CROSS APPLY sys.dm_exec_sql_text(plan_handle) AS st WHERE [text] LIKE N'%CASE WHEN opgv.lngpaymentID IS NULL THEN NULL%';
假設該字元串未在其他查詢中使用,結果應該只返回幾行。然後,您將查看該
st.[text]
列以確保您擁有正確的 plan_handle,然後使用該 plan_handleDBCC FREEPROCCACHE
將其從計劃記憶體中刪除。作為旁注,我會非常小心地針對實時生產系統執行 SSMS 會話 - 這可能是災難的根源,因為很容易忘記您正在生產伺服器上工作。