sql >> Databasteknik >  >> RDS >> Database

Undviker knee-Jerk prestanda felsökning

Prestandafelsökning är en konst och en vetenskap. Konsten kommer från erfarenhet (och lärande av andras erfarenheter) och vetenskapen kommer från välkända riktlinjer om vad man ska göra i vilka scenarier.

Eller det är åtminstone vad jag tycker om att tänka och lära ut.

I verkligheten utövar många DBA:er och utvecklare där ute vad jag kallar "knee-jerk performance felsökning". Detta händer vanligtvis när ett prestandaproblem har nått det kritiska skedet med till exempel att frågor tar slut, processer som går långsamt eller misslyckas, användare är missnöjda och ledningen vill ha svar och åtgärder snabbt!

"Knee-jerk" kommer från att göra en ytlig analys av problemet och dra till slutsatsen (det är verkligen att greppa efter ett halmstrå) att det vanligaste symtomet måste vara grundorsaken och försöka lösa det, till ingen eller liten nytta, använder ofta missriktade eller direkt felaktiga råd som finns på nätet. Detta leder till mycket frustration och slöseri med tid, och leder ofta till bortkastade pengar när organisationen bestämmer sig för att försöka kasta hårdvara på problemet genom att uppgradera servern och/eller I/O-undersystemet, bara för att upptäcka att problemet kvarstår. , eller dyker upp ganska snabbt igen.

Väntestatistikanalys är ett av de områden där det är lättast att få knä, och i det här inlägget kommer jag att prata om några av de vanliga väntetyperna och de misstag som människor gör runt dem. Det finns inget utrymme i en artikel som denna att gå in på djupet om vad du ska göra i varje enskilt fall, men jag ska ge dig tillräckligt med information för att peka dig i rätt riktning.

LCK_M_XX

De flesta antar att om låsning väntar är vanligast, så måste det vara något slags blockeringsproblem som är problemet. Ofta är det, som att bristen på ett lämpligt icke-klustrat index orsakar en tabellsökning i REPEATABLE_READ eller SERIALIZABLE isoleringsnivåer som eskalerar till ett S-tabelllås. (Och som ett snabbt tips, om du inte tror att du någonsin använder SERIALIZABLE, så gör du det om du använder distribuerade transaktioner – allt konverteras till SERIALIZABLE under täcket, vilket kan leda till oväntad blockering och dödlägen.)

Men det är ofta så att blockeringen orsakas av något annat. Under standardisoleringsnivån READ_COMMITTED hålls lås som täcker ändringar tills transaktionen genomförs, och blockerar läsningar och andra uppdateringar till samma rad(er). Om något hindrar en transaktion från att genomföras kan det göra att blockering dyker upp.

Till exempel, om databasen speglas synkront, kan transaktionen inte begå och frigöra sina lås förrän loggposterna har skickats över till spegeln och skrivits till spegelns loggenhet. Om nätverket är allvarligt överbelastat, eller om det finns massiva I/O-konflikter på spegeln, kan detta allvarligt försena speglingsoperationen och göra att transaktionen tar mycket längre tid att genomföra. Detta skulle se ut som blockering, men grundorsaken är resursstridigheter som har att göra med spegling.

För låsning väntar, såvida inte orsaken är uppenbar från att titta på frågeplanen, lås resurs (t.ex. tabellnivå som indikerar låseskalering eller isoleringsnivå, följ blockeringskedjan (med hjälp av ett skript som går i kolumnen blocking_session_id i sys.dm_exec_requests och sedan titta för att se vad tråden i spetsen av blockeringskedjan väntar på. Det kommer att peka på grundorsaken.

ASYNC_NETWORK_IO

Namnet på den här orsakar mycket förvirring. Vilket ord fokuserar du på? NÄTVERK. Orsaken till denna väntetyp har vanligtvis inget med nätverket att göra. Det borde egentligen heta WAITING_FOR_APP_ACK (nowledgment), eller något liknande, eftersom det är precis vad som händer:SQL Server har skickat en del data till en klient och väntar på att klienten ska erkänna att den har förbrukat data.

En av mina favoritdemos att göra när jag lär mig om väntestatistik är att köra en fråga som returnerar en stor resultatuppsättning i Management Studio och se servern samla ASYNC_NETWORK_IO-väntningar. Det finns uppenbarligen inget nätverk inblandat – det är bara SSMS som tar lång tid att svara på SQL Server. Den gör det som kallas RBAR (Row-By-Agonizing-Row), där bara en rad åt gången hämtas från resultaten och bearbetas, istället för att cachelagra alla resultat och sedan omedelbart svara till SQL Server och fortsätta att bearbeta cachade rader.

Detta är den främsta orsaken till ASYNC_NETWORK_IO väntan – dålig applikationsdesign. Jag skulle sedan titta på om servern som kör applikationskoden har ett prestandaproblem, även om applikationskoden i sig är väl utformad. Ibland är det nätverket, men det är sällsynt enligt min erfarenhet.

OLEDB

Den vanligaste reaktionen här är att likställa denna väntetyp med länkade servrar. Men denna väntetid blev vanligare att se när SQL Server 2005 levererades, eftersom 2005 innehöll en mängd nya DMV:er, och DMV:er använder mest OLE DB under täcket. Innan jag letade efter problem med länkade server, skulle jag kontrollera om ett övervakningsverktyg kör DMVs konstant på servern.

Om du har länkade servrar, fortsätt felsökningen genom att gå till den länkade servern och titta på väntestatistiken där för att se vad det vanligaste problemet är, och fortsätt sedan samma analys.

En annan sak som kan orsaka OLEDB-väntningar är DBCC CHECKDB (och relaterade kommandon). Den använder en OLE DB-raduppsättning för att kommunicera information mellan dess Query Processor och Storage Engine-undersystem.

Andra väntan

Några av de andra väntetiderna som orsakar knäna är CXPACKET, PAGEIOLATCH_XX, SOS_SCHEDULER_YIELD och WRITELOG, och jag kommer att ta upp dem i mitt inlägg nästa månad.

Sammanfattning

När du har ett prestandaproblem, ta dig tid att förstå informationen du tittar på och utför ytterligare undersökningar för att hjälpa dig att begränsa till grundorsaken till problemet. Ta inte bara tag i det som verkar vara den bästa väntestatistiken och följ det första rådet du stöter på online (såvida det inte kommer från en välkänd och ansedd källa) annars kommer du förmodligen inte att lösa ditt problem, och kanske t.o.m. gör det värre.

När det gäller allmän väntestatistik kan du hitta mer information om hur du använder dem för prestandafelsökning i:

  • Min blogginläggsserie, som börjar med Vänta statistik, eller snälla berätta för mig var det gör ont
  • Mina väntetyper och låsklasser-bibliotek här
  • Min Pluralsight onlinekurs SQL Server:Prestandafelsökning med hjälp av väntastatistik
  • SQL Sentry Performance Advisor

Det här var det första i en serie av inlägg jag kommer att göra under loppet av detta år som talar om knä-ryck (re)aktioner kring SQL Server och varför de är fel sak att göra. Tills nästa gång, lycklig felsökning!


  1. ORA-12505, TNS:listener känner för närvarande inte till SID som ges i anslutningsbeskrivningen

  2. NEWID() vs NEWSEQUENTIALID() i SQL Server:Vad är skillnaden?

  3. Upptäck om ett värde innehåller minst en numerisk siffra i SQLite

  4. CURRENT_TIMESTAMP() Funktion i Oracle