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
Was it helpful?

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with dba.stackexchange
scroll top