Un formular care se deschide în mai puțin de o secundă într-o rețea locală durează cinci secunde prin VPN, în timp ce o copie de fișier pe același link merge la viteză maximă. Diferența nu este lățimea de bandă. Formularul așteaptă o succesiune de răspunsuri și plătește dus-întorsul complet la fiecare pas, în timp ce copia de fișier ține octeții continuu în zbor. Numără aceste așteptări înainte să atingi linia de acces.

Simptomul este un ecran, nu o interogare

Fiecare interogare de pe acel ecran poate fi rapidă și ecranul poate rămâne lent, pentru că totalul este suma așteptărilor, nu suma timpilor de execuție. O instrucțiune care rulează în două milisecunde costă totuși un dus-întors complet atunci când clientul trebuie să primească rezultatul înainte de a-l trimite pe următorul. Pe o cale cu patruzeci de milisecunde de latență, o sută de apeluri dependente se adună la aproximativ patru secunde înainte să înceapă orice lucru de randare. Această aritmetică este un model al așteptării, nu o măsurătoare a linkului tău.

De aceea un test de viteză pare nevinovat. Transferul în bloc măsoară debitul, un formular vorbăreț măsoară latența, iar un VPN poate fi excelent la una și obișnuit la cealaltă. A diagnostica ecranul înseamnă deci a măsura ecranul, nu linkul.

Notează timpul de la un capăt la altul al unei acțiuni a utilizatorului înainte de a schimba ceva. Acel număr este singura referință care îți poate spune dacă o corecție ulterioară a funcționat.

Numără așteptările secvențiale dintr-o acțiune a utilizatorului

Instrumentează clientul în loc să ghicești. În psql, \timing on afișează timpul scurs pentru fiecare instrucțiune, iar EXPLAIN (ANALYZE, BUFFERS) arată cât din acel timp a petrecut serverul efectiv pe lucru.

Diferența dintre aceste două numere este costul tău de rețea și de client. Dacă o instrucțiune se execută în două milisecunde, iar clientul înregistrează șaizeci, restul de cincizeci și opt sunt călătorie și procesare locală, iar niciun index nu le va elimina. Repetă comparația pentru fiecare instrucțiune emisă de ecran și adună diferențele, nu timpii de execuție.

Notează rezultatul ca număr de așteptări secvențiale. Aceasta este mărimea pe care următoarele două secțiuni o pot reduce și este un număr despre care poți argumenta cu dovezi.

Grupează apelurile independente, păstrează-le pe cele dependente

Două instrucțiuni care nu citesc rezultatul unele altora pot călători împreună și pot fi colectate o dată, ceea ce transformă două așteptări într-una. Două instrucțiuni în care a doua are nevoie de valoarea primei nu pot, pentru că dependența este reală și gruparea ar schimba ce face programul. Sortează apelurile în cele două grămezi înainte de a rescrie ceva, iar mărimea fiecărei grămezi îți spune ce este posibil.

Munca pe seturi elimină așteptările mai temeinic decât gruparea. O singură interogare care returnează rândurile pe care o buclă le lua unul câte unul elimină bucla, precum și dus-întorsurile. Caută mai întâi bucla, pentru că de obicei este câștigul mai mare și schimbarea mai ușor de revizuit.

Un lot trebuie totuși să păstreze tratarea erorilor și granițele tranzacțiilor. Concatenarea unor instrucțiuni fără legătură într-un singur șir nu este o optimizare sigură, iar un lot care ascunde o instrucțiune eșuată în spatele unei trimiteri reușite este mai rău decât așteptările pe care le-a economisit.

Reutilizează conexiunile înainte de a cumpăra lățime de bandă

O conexiune nouă costă rezolvare de nume, un handshake TCP, negociere TLS și autentificare, iar pe o cale cu latență mare fiecare dintre acestea este încă un dus-întors înainte ca prima interogare să ruleze. Pool-urile de conexiuni există pentru a plăti acest cost o dată pe proces, nu o dată pe apel.

În ADO.NET, închiderea sau eliminarea unei conexiuni din pool o returnează pentru reutilizare în loc să deschidă una fizică nouă, așa că tiparul care pare o scurgere este adesea utilizarea corectă. Verifică dacă pool-ul este cu adevărat folosit în loc să presupui: înregistrează în log crearea conexiunilor fizice sau urmărește numărul de sesiuni de pe server în timp ce ecranul rulează. Ghidul de performanță SQL spune același lucru despre reducerea dus-întorsurilor și gruparea apelurilor ad hoc frecvente, cu exemple specifice serviciului pe care ar trebui să le aplici implementării tale.

Pooling-ul elimină costul de configurare și lasă așteptările secvențiale ale interogărilor neatinse. Este o condiție prealabilă pentru o măsurătoare curată, nu o corecție de sine stătătoare.

Cântărește mutarea execuției mai aproape de date

Rularea aplicației lângă baza de date înlocuiește multe schimburi remote cu baza de date cu o singură sesiune remote de afișare. Pentru o încărcare vorbăreață aceasta poate fi o schimbare mare și este o schimbare operațională tot atât cât una de performanță: gestionarea sesiunilor, controlul accesului, implementarea software și experiența utilizatorului se mută toate împreună cu aplicația.

Măsoară interfața reală și datele pe care le transferă înainte de a presupune că vreo direcție este mai rapidă. O sesiune de desktop remote mută pixeli, iar un ecran cu grafică densă poate funcționa mai prost pe aceeași cale decât interogările pe care le-a înlocuit, mai ales când clientul redesenează continuu.

Apoi repetă acțiunea originală și compară trei numere: așteptări secvențiale, volumul rezultatelor și timpul de finalizare de la un capăt la altul. O îmbunătățire care schimbă sarcina măsurată a utilizatorului păstrând corectitudinea datelor și politica de acces este cea care merită păstrată.

Articole similare