SQL Server are un pool de memorie pentru stocarea planurilor de execuție și a tampoanelor de date. Procentul mărimii piscinei alocate pentru planurile de execuție și tampoanele de date variază în mod dinamic, în funcție de starea sistemului. O porțiune din grupul de memorie utilizat pentru stocarea planurilor de execuție se numește memoria cache a procedurii.
În SQL Server, planurile de execuție constau din următoarele componente principale.
Organismul planului de execuție este o structură de date care reintră în citire și care este destinată utilizării de către orice număr de utilizatori. Se numește un plan de interogare. Planul interogării nu conține contextul utilizatorului. Nu pot exista mai mult de una sau două copii ale planului de interogare în memorie: una pentru toate execuțiile consecutive și una pentru toate execuțiile paralele. O copie paralelă servește tuturor execuțiilor paralele indiferent de gradul de paralelism.
Pentru fiecare utilizator care execută în prezent interogarea, există o structură de date care conține date relevante pentru execuție, de exemplu, valori ale parametrilor. Această structură de date se numește context de execuție. Structurile de date ale contextului de execuție sunt reutilizabile. Dacă utilizatorul execută interogarea și una dintre structuri nu este utilizată, aceasta este reinitializată de contextul noului utilizator.
În SQL Server, când se execută o instrucțiune SQL, motorul relațional se uită mai întâi la cache-ul procedurii, verificând dacă nu are un plan de execuție pentru aceeași instrucțiune. SQL Server reutilizează orice plan de execuție pe care îl găsește, reducând costul re-compilării sale. Dacă nu se găsește niciun plan existent, SQL Server generează un nou plan pentru această interogare.
SQL Server implementează un algoritm eficient pentru găsirea planurilor de execuție existente pentru orice instrucțiune SQL. În majoritatea sistemelor, resursele cheltuite pentru căutarea unui plan finit sunt întotdeauna mai puțin decât resursele necesare pentru re-compilarea fiecărei instrucțiuni SQL.
Algoritmii pentru potrivirea unei instrucțiuni SQL cu un plan existent de execuție neutilizat din memoria cache necesită completarea tuturor referințelor de obiecte. De exemplu, pentru prima dintre următoarele instrucțiuni SELECT, planul existent nu va fi în concordanță, iar pentru al doilea, acesta va fi:
Planurile de execuție rămân în cache-ul procedurii, atâta timp cât există suficientă memorie pentru stocarea acestora. Dacă există o lipsă de memorie, motorul bazei de date utilizează abordarea bazată pe costuri pentru a determina planul de execuție pe care doriți să îl eliminați din memoria cache a procedurii. Pentru a face o soluție bazată pe cost, motorul bazei de date mărește și scade variabila de valoare prezentă pentru fiecare plan de execuție, pe baza următorilor factori.
Atunci când un proces personalizat adaugă un plan de execuție în cache, acesta stabilește costul curent la aceeași valoare ca interogarea originală. Pentru planurile de execuție neplanificate, procesul de utilizator stabilește valoarea costului curent la zero. După aceasta, de fiecare dată când procesul de utilizator se referă la planul de execuție, acesta resetează valoarea curentă, făcându-l egal cu costul original de compilare. Pentru planurile ad hoc, procesul de utilizator crește valoarea valorii curente. Pentru toate planurile, valoarea maximă a valorii curente este egală cu costul inițial de compilare.
Dacă există o lipsă de memorie, motorul bazei de date răspunde la aceasta prin eliminarea planurilor de execuție din cache-ul procedurii. Pentru a determina care planuri de eliminare, motorul bazei de date verifică în mod repetat starea fiecărui plan de execuție și șterge cele pentru care costul curent este zero. Planul de execuție cu valoarea curentului zero nu este șters automat dacă există o lipsă de memorie; acesta este șters numai după verificarea de către motorul bazei de date dacă costul său curent este zero. Când verificați planul de execuție, motorul bazei de date aduce costul curent la zero, reducându-l dacă interogarea nu utilizează în prezent planul.
Motorul bazei de date verifică în mod repetat planurile de execuție până când se îndepărtează suficient pentru a satisface cerințele de memorie. Dacă există o lipsă de memorie, costul planului de execuție poate crește și scădea de mai multe ori. Când lipsa memoriei a dispărut, motorul de baze de date întrerupe scăderea costului actual al planurilor de execuție neutilizate și toate planurile de execuție rămân în cache-ul procedurii, chiar dacă costul lor este zero.
Motorul bazei de date utilizează monitorul de resurse și firele utilizatorilor pentru a elibera memoria ocupată de cache-ul procedurii atunci când are loc o lipsă de memorie. Monitorul de resurse și firele utilizatorului pot verifica planurile paralele, ceea ce vă permite să reduceți costul curent pentru fiecare plan de execuție neutilizat. Monitorul de resurse elimină planurile de execuție din cache-ul procedurii dacă există o lipsă de memorie globală. Eliberă memorie pentru a impune politici pentru memoria sistemului, memoria procesului, memoria bazei de resurse și mărimea maximă a tuturor cache-urilor.
Dimensiunea maximă a tuturor cache-urilor este o funcție a mărimii pool-ului buffer și nu poate depăși suma maximă a memoriei serverului. Pentru mai multe informații despre configurarea dimensiunii maxime a memoriei serverului, consultați opțiunea de memorie maximă a serverului din secțiunea sp_configure (Transact-SQL).
Firele utilizator elimină planurile de execuție din cache-ul procedurii dacă există o lipsă de memorie într-o singură memorie cache. Ele oferă executarea de politici pentru dimensiunea maximă a cache-ului și maximul intrărilor cache unice.
Următoarele exemple arată ce planuri de execuție sunt eliminate din cache-ul procedurii.
Planul de execuție este adesea folosit, deci valoarea sa nu ia niciodată o valoare de zero. Acest plan rămâne în cache-ul procedurii și nu este șters până când nu există suficientă memorie, iar costul său curent nu este zero.
Se inserează un plan de execuție neplanificat și nu se utilizează până la apariția unei deficite de memorie. Deoarece planurile de execuție ad-hoc sunt inițializate cu o valoare curentă care este zero, când verificați planul de execuție, Database Engine detectează o valoare curentă zero și planul este eliminat din cache-ul procedurii. Un plan de execuție nereglementat, cu valoarea zero actuală, rămâne în cache-ul procedurii atunci când există suficientă memorie.
Pentru a șterge manual un singur plan de execuție sau toate planurile, utilizați comanda DBCC FREEPROCCACHE (Transact-SQL).
Unele modificări ale bazei de date pot determina modificarea planului de execuție atunci când modificările de stare devin ineficiente sau incorecte. SQL Server detectează modificări care pot face planul de execuție nevalid și marchează planul ca incorect. Data viitoare când interogarea este executată, planul trebuie recompilat. Planul poate deveni invalid în următoarele cazuri.
A fost modificată tabela sau vizualizările la care se referă interogarea (ALTER TABLE sau ALTER VIEW).
Indicii utilizați de planul de execuție au fost modificați.
Statisticile actualizate utilizate de planul de execuție, formate fie explicit prin UPDATE STATISTICS, fie automat.
Indicii utilizați de planul de execuție sunt eliminați.
Explicat numit procedura sp_recompile.
Modificări frecvente ale tastelor (instrucțiuni INSERT sau DELETE de la utilizatori care modifică tabela la care se referă interogarea).
Pentru tabele cu triggere: o creștere semnificativă a numărului de rânduri din tabelele inserate și șterse.
Executarea unei proceduri memorate cu parametrul WITH RECOMPILE.
Majoritatea recompilărilor sunt necesare fie pentru a asigura corectitudinea instrucțiunilor, fie pentru a accelera potențial planul de execuție.
Recompilarea la nivelul instrucțiunilor duce la câștiguri de performanță, deoarece în majoritatea cazurilor recompilarea unui număr mic de instrucțiuni și pierderile asociate necesită mai puține resurse în ceea ce privește timpul procesorului și costurile de blocare. Aceste pierderi sunt astfel evitate pentru restul instrucțiunilor pachetului, care nu necesită o recompilare.
Exemplu de urmărire SQL: StmtRecompile afișează informații despre recompilare la nivelul instrucțiunilor. Acesta poate fi utilizat pentru urmărirea și depanarea recompilărilor. Evenimentul SP: Recompile este creat numai pentru procedurile și declanșatoarele stocate și SQL: StmtRecompile pentru procedurile stocate, declanșatoarele, pachetele speciale și pachetele care se execută prin sp_executesql. interogări pregătite și SQL dinamic.
Coloana EventSubClass pentru evenimentele SP: Recompile și SQL: StmtRecompile conține un cod întreg care indică motivul recompilației. Următorul tabel prezintă valorile pentru fiecare dintre aceste coduri.