DBCC freeproccache?

întrebările dvs. sunt peste tot, așa că voi încerca să le abordez pe toate. Cache-ul de procedură este doar atât de mare. Este posibil ca memoria cache a procedurii să fi fost completată cu planuri de unică folosință (acest lucru nu are niciun impact asupra statisticilor, deși statisticile pot afecta memoria cache a planului). Puteți citi o mulțime de detalii despre planurile de unică folosință în postarea de pe blogul lui Kimberly Tripp, „planificați memoria cache și optimizarea pentru sarcinile de lucru adhoc”-inclusiv o interogare împotriva sys.dm_exec_cached_plans care vă va ajuta să identificați când memoria cache este populată cu o mulțime de planuri de unică folosință. După cum sugerează ea, puteți preveni această balonare utilizând optimizați pentru sarcini de lucru ad-hoc. Dacă găsiți necesitatea de a face acest lucru de multe ori, aș spune că programarea freeproccache ca un loc de muncă este un band-aid, nu o soluție.

pentru a șterge un plan „rău”, mai întâi trebuie să identificați planul „rău”. Acesta ar putea fi un plan care depășește o anumită dimensiune și/sau nu a fost executat de ceva timp sau pe care l-ați identificat printr-o interogare de lungă durată etc. Din păcate, nu este simplu de a identifica un plan care este o victimă a parametru sniffing excepția cazului în care știți deja interogarea sau interogările care sunt afectate. Să presupunem că doriți să găsiți cele mai vechi planuri din memoria cache care nu a fost rulată de peste o săptămână:

;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;

acum trebuie să verificați dacă doriți cu adevărat să clarificați acest plan. De exemplu, dacă recunoașteți acea interogare ca fiind ceva ce CEO-ul ar putea rula mâine, poate că este mai bine să o lăsați acolo. Dacă doriți să ștergeți planul, îl puteți șterge direct spunând:

DBCC FREEPROCCACHE();

acest lucru pare a fi mult mai multă muncă decât rularea DBCC FREEPROCCACHE la nivel global, dar dacă aveți o mulțime de planuri bune în cache, cu siguranță va fi mai bine pentru utilizatorii dvs. în general.

totuși, sună ca un plasture. Dacă memoria cache se umple cu junk și performanța merge în toaletă până când eliberați memoria cache, trebuie să vă uitați la un nivel superior la arhitectură, la modul în care sunt trimise interogările etc. Acesta este comportamentul pe care l-aș aștepta de la prima iterație a LINQ2SQL, unde ar cache o versiune a unui plan pentru o interogare pentru fiecare argument șir care avea o lungime diferită. Deci, dacă ați avea un parametru de ‘ianuarie’, veți obține un plan diferit decât cu un parametru de’ februarie’, deoarece ar defini tipul de date ca VARCHAR(7) vs. VARCHAR(8). Destul de sigur că comportamentul este fix, dar nu știu suficient despre mediul / aplicația dvs. pentru a sugera unde să căutați exact „idei proaste.”