sql >> Database teknologi >  >> RDS >> Database

Ydeevne overraskelser og antagelser:SÆT ANTAL TIL

Hvis du nogensinde har brugt Management Studio, vil denne outputmeddelelse sandsynligvis se bekendt ud:

(1 række(r) påvirket)

Dette kommer fra SQL Servers DONE_IN_PROC meddelelse, som sendes ved succesfuld afslutning af enhver SQL-sætning, der har returneret et resultat (inklusive hentning af en eksekveringsplan, hvilket er grunden til, at du ser to af disse meddelelser, når du faktisk kun har udført en enkelt forespørgsel).

Du kan undertrykke disse beskeder med følgende kommando:

SET NOCOUNT ON;

Hvorfor ville du gøre det? Fordi disse beskeder er chatty og ofte ubrugelig . I mine præsentationer om dårlige vaner og bedste praksis taler jeg ofte om at tilføje SET NOCOUNT ON; til alle lagrede procedurer, og slå det til i applikationskode, der sender ad hoc-forespørgsler. (Under debugging vil du dog måske have et flag for at tænde for beskederne igen, da outputtet kan være nyttigt i disse tilfælde.)

Jeg har altid tilføjet ansvarsfraskrivelsen, at rådet om at slå denne mulighed til overalt ikke er universelt; det kommer an på. Old-school ADO-rekordsæt fortolkede disse som resultatsæt, så at tilføje dem til forespørgslerne efter kendsgerningen kunne faktisk ødelægge applikation(er), der allerede manuelt springer dem over. Og nogle ORM'er (hoste NHibernate hoste ) parser faktisk resultaterne for at bestemme succesen af ​​DML-kommandoer (ugh!). Test venligst dine ændringer.

Jeg ved, at jeg på et tidspunkt havde bevist over for mig selv, at disse chatty beskeder kunne påvirke ydeevnen, især over et langsomt netværk. Men det er længe siden, og i sidste uge spurgte Erin Stellato mig, om jeg nogensinde havde dokumenteret det formelt. Det har jeg ikke, så her kommer. Vi tager en meget simpel løkke, hvor vi opdaterer en tabelvariabel en million gange:

SET NOCOUNT OFF;
 
DECLARE @i INT = 1;
DECLARE @x TABLE(a INT);
INSERT @x(a) VALUES(1);
 
SELECT SYSDATETIME();
 
WHILE @i < 1000000
BEGIN
  UPDATE @x SET a = 1;
  SET @i += 1;
END
 
SELECT SYSDATETIME();

Et par ting, du måske bemærker:

  • Meddelelsesruden er oversvømmet med forekomster af (1 row(s) affected) besked:

  • Initial SELECT SYSDATETIME(); vises ikke i resultatruden, før hele batchen er afsluttet. Dette er på grund af oversvømmelsen.
  • Denne batch tog omkring 21 sekunder at køre.

Lad os nu gentage dette uden DONE_IN_PROC beskeder, ved at ændre SET NOCOUNT OFF; for at SET NOCOUNT ON; og kør det igen.

Selvom meddelelsesruden ikke længere var oversvømmet med række(r) berørte meddelelser, tog batchen stadig ~21 sekunder at køre.

Så tænkte jeg, vent et øjeblik, jeg ved, hvad der foregår. Jeg er på en lokal maskine, uden netværk involveret, og bruger delt hukommelse, jeg har kun SSD og masser af RAM...

Så jeg gentog testene ved at bruge min lokale kopi af SSMS mod en ekstern Azure SQL-database – en Standard, S0, V12. Denne gang tog forespørgslerne meget længere, selv efter at have reduceret gentagelserne fra 1.000.000 til 100.000. Men igen var der ingen mærkbar forskel i ydeevnen, om DONE_IN_PROC beskeder blev sendt eller ej. Begge batches tog omkring 104 sekunder, og dette kunne gentages over mange iterationer.

Konklusion

I årevis havde jeg opereret under det indtryk, at SET NOCOUNT ON; var en kritisk del af enhver præstationsstrategi. Dette var baseret på observationer, jeg havde gjort i, velsagtens, en anden æra, og som er mindre tilbøjelige til at manifestere sig i dag.

Når det er sagt, vil jeg fortsætte med at bruge SET NOCOUNT ON , selvom der på dagens hardware ikke er nogen mærkbar forskel i ydeevnen. Jeg føler stadig ret stærkt for at minimere netværkstrafikken, hvor det er muligt. Jeg bør overveje at implementere en test, hvor jeg har meget mere begrænset båndbredde (måske har nogen en AOL-cd, de kan låne mig?), eller have en maskine, hvor mængden af ​​hukommelse er lavere end Management Studios outputbuffergrænser, for at være sikker på, at der er ikke en potentiel indvirkning i worst-case scenarier. I mellemtiden, selvom det måske ikke ændrer den opfattede ydeevne om din applikation, kan det stadig hjælpe din tegnebog til altid at slå denne indstillingsmulighed til, især i situationer som Azure – hvor du kan blive opkrævet for udgående trafik.


  1. Konverter hex i tekstrepræsentation til decimaltal

  2. Sådan installeres SQL Server på en Mac med VirtualBox

  3. Det indre af MED KRYPTERING

  4. Sådan installeres Cassandra v3 på CentOS 6