DBCC freeproccache?
dina frågor är överallt, så jag ska försöka ta itu med dem alla. Procedurcachen är bara så stor. Din procedurcache kan ha fyllts med engångsplaner (detta har ingen inverkan på statistiken, men statistiken kan påverka plancachen). Du kan läsa mycket information om engångsplaner i Kimberly Tripps blogginlägg, ”planera cache och optimera för adhoc-arbetsbelastningar” – inklusive en fråga mot sys.dm_exec_cached_plans som hjälper till att identifiera när cachen är befolkad med många engångsplaner. Som hon föreslår kan du förhindra denna uppblåsthet genom att använda Optimera för ad hoc-arbetsbelastningar. Om du hittar behovet av att göra detta ofta, skulle jag säga att schemaläggning freeproccache som ett jobb är ett plåster, inte en lösning.
för att rensa ut en ”dålig” plan måste du först identifiera den ”dåliga” Planen. Det här kan vara en plan som överstiger en viss storlek och / eller inte har utförts på en tid, eller som du har identifierat med en långvarig fråga etc. Tyvärr är det inte enkelt att identifiera en plan som är offer för parametersniffning om du inte redan känner till frågan eller frågorna som påverkas. Låt oss anta att du vill hitta de äldsta planerna i cachen som inte har körts på över en vecka:
;WITH x AS ( SELECT TOP 10 qs., qs.plan_handle, txs = qs.statement_start_offset, txe = qs.statement_end_offset, = cp.size_in_bytes, = SUM(cp.usecounts), = MAX(qs.last_execution_time) FROM sys.dm_exec_query_stats AS qs INNER JOIN sys.dm_exec_cached_plans AS cp ON qs.plan_handle = cp.plan_handle WHERE qs.last_execution_time < DATEADD(DAY, -7, CURRENT_TIMESTAMP) GROUP BY qs., qs.plan_handle, cp.size_in_bytes, qs.statement_start_offset, qs.statement_end_offset ORDER BY DESC) SELECT x.plan_handle, size, uses, , = COALESCE(NULLIF( SUBSTRING(t., x.txs/2, CASE WHEN x.txe = -1 THEN 0 ELSE (x.txe - x.txs)/2 END ), ''), t.) FROM x CROSS APPLY sys.dm_exec_sql_text(x.) AS t;
nu måste du verifiera att du verkligen vill rensa ut den här planen. Om du till exempel känner igen den frågan som något som VD kan köra imorgon, kanske det är bäst att lämna den där. Om du vill rensa planen kan du rensa den direkt genom att säga:
DBCC FREEPROCCACHE();
det här låter som mycket mer arbete än att köra DBCC FREEPROCCACHE
globalt, men om du har många bra planer i cachen kommer det säkert att bli bättre för dina användare totalt sett.
ändå låter det verkligen som ett bandhjälp. Om din cache fylls med skräp och prestanda går på toaletten tills du frigör cachen måste du titta på en högre nivå på arkitekturen, hur frågor skickas in etc. Detta är beteendet jag förväntar mig från den allra första iterationen av LINQ2SQL, där det skulle cache en version av en plan för en fråga för varje strängargument som var en annan längd. Så om du hade en parameter av ’januari’ skulle du få en annan plan än med en parameter av ’februari’ eftersom det skulle definiera datatypen som VARCHAR(7)
vs. VARCHAR(8)
. Ganska säker på att beteendet är fixat men jag vet inte tillräckligt om din miljö / applikation för att föreslå var exakt att leta efter ”dåliga ideer.”