how to clear only the query plans from the current session?
-
01-10-2020 - |
Question
I am working on tuning a query on a very busy server, where I don't want to clear the cache, using DBCC FREEPROCCACHE
;
I know it will cause at least a CPU spike, and in this case I don't want it.
here in this article it shows how to clear the cache for an specific database only.
-- 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);
I would like to do something like this:
-- 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);
Is there any way I can locate the query that I am working on, or at lease my own session in the cache?
I am tuning the query below:
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
Solution
Marcello, it seems you have the answer in your question, albeit with one minor modification.
The query:
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 %';
contains the term '%/* GetOnlineSearchResultsMondy %'
, which is a wild-card search used to locate the specific plan to remove from the cache. If you ran it with a search term contained within the query you are attempting to tune, it should return a plan handle that can then be used with DBCC FREEPROCCACHE
:
-- Remove the specific plan from the cache using the plan handle
DBCC FREEPROCCACHE (0x05000800F7BA926C40C15055070000000000000000000000);
I would suggest perhaps using the following to identify the query:
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%';
Assuming that string is not used in other queries, the results should only return a few rows. You would then look at the st.[text]
column to ensure you have the correct plan_handle, then use that plan_handle with DBCC FREEPROCCACHE
to remove it from the plan cache.
As a side-note, I would be very careful running an SSMS session against a live production system - it can be a recipe for disaster, since it is very easy to forget your are working on the production server.