sql >> Databasteknik >  >> RDS >> Sqlserver

Felsökning av långvariga frågor i MS SQL Server

Förord

Det finns ett informationssystem som jag administrerar. Systemet består av följande komponenter:

1. MS SQL Server-databas
2. Serverapplikation
3. Klientapplikationer

Dessa informationssystem är installerade på flera objekt. Informationssystemet används aktivt 24 timmar om dygnet av 2 till 20 användare samtidigt på varje objekt. Därför kan du inte utföra rutinunderhåll på en gång. Så jag måste "sprida" SQL Server-indexdefragmentering över dagen, snarare än att defragmentera alla nödvändiga fragmenterade index i ett slag. Detta gäller även andra verksamheter.

Egenskapen för automatisk uppdatering av statistik ställs in i databasens egenskaper. Dessutom uppdateras statistiken på det defragmenterade indexet.

Problem

För ungefär ett år sedan stötte jag på följande problem:

Från tid till annan gick alla frågor långsamt. Noterbart var fördröjningstiden slumpmässig. Det hände på varje föremål en slumpmässig dag. Dessutom, när jag började analysera hur ofta förseningarna inträffar (med hjälp av profileringsverktyget), fick jag reda på att de inträffar varje dag vid en slumpmässig tidpunkt. Användare uppmärksammar dem helt enkelt inte alltid utan tar dem som den enda slumpmässiga fördröjningen, och sedan fungerar systemet snabbt igen.

Lösa problemet

Jag har granskat alla långsamma frågor. Det märkligaste var att alla frågor gick långsamt vid en slumpmässig tidpunkt, även de enklaste, som att hämta den sista posten från en tabell med flera tusen rader.

Vidare utförde jag följande steg:

1. Jag analyserade MS SQL Server- och Windows Server-loggar, men kunde inte hitta orsaken till förseningarna.
2. Jag analyserade index (fragmentering etc.), la till de saknade och tog bort oanvända.
3. Jag analyserade frågorna – vissa frågor förbättrades.
4. Jag analyserade uppgifterna i SQL Agent och kunde inte associera uppgifterna med fördröjningsproblemet.
5. Jag analyserade uppgifterna i Task Scheduler och kunde inte associera uppgifterna med fördröjningsproblemet.
6. Profiler visade resultaten, men inte orsaken till förseningarna.
7. Jag gjorde en kontroll för dödläge – inga långa blockeringar avslöjades.

Som ett resultat tillbringade jag mer än 3 månader på den misslyckade sökningen efter orsaken till enstaka långsamma frågor. Men jag avslöjade ett intressant faktum - istället för indikatorn för Worker execution, ökade indikatorn för förfluten väntan för alla frågor. Detta faktum gav mig idén att något är fel med diskarna. Jag kollade dem – allt var bra.

Lösning

Till min förvåning avslöjade jag av misstag att när en fråga kördes långsamt i applikationen, så körde den snabbt i SSMS. En artikel hjälpte till att lösa problemet (den föreslog åtminstone idén).

Ett stycke från artikeln:

I praktiken är det viktigaste SET-alternativet ARITHABORT, eftersom standardvärdet för detta alternativ är annorlunda för applikationer och för SQL Server Management Studio. Detta förklarar varför du kan upptäcka en långsam fråga i din applikation och sedan få bra hastighet genom att köra den i SSMS. Applikationen använder en plan som byggdes för en uppsättning värden som skiljer sig från de faktiska korrekta värdena. Om du kör frågan i SSMS är det mest troligt att cachen ännu inte har en exekveringsplan för ARITHABORT ON, och därför kommer SQL Server att bygga en plan för dina nuvarande värden.

Skillnaden i exekvering berodde på parametern SET ARITHABORT. För alla frågor som körs i SSMS är det här alternativet aktiverat och för frågor utifrån (från applikationer) – inaktiverat. Det kan inte aktiveras ens med en enkel fråga för applikationer:

SET ARITHABORT ON;

En galen idé följde – rensa procedurcache vid tidpunkten för avbrottet.

För den efterföljande manuella kontrollen måste jag skriva följande uttalande före frågan i SSMS:

SET ARITHABORT OFF;

På så sätt kommer vi att simulera applikationens funktion. När frågan hade körts länge rensade jag procedurcachen. Och detta hjälpte alltid. Innan du rensar procedurcachen kunde frågan köra upp till 20-30 sekunder och efteråt – 0 sekunder.

Efter det utförde jag ett nytt experiment – ​​rengöra hela procedurcachen för hela databasen varje timme via SQL Agent:

--cleaning the cache by database id
DBCC FLUSHPROCINDB (@db_id);

Efter det gick alla frågor mycket snabbt (mindre än 0,05 sekunder). Det förekom bara några förekomster av upp till 5-10 sekunders avrättning, men användarna märkte inga avbrott. Dessutom förbättrade inte uppdateringen av statistiken resultaten, så jag inaktiverade statistikuppdateringen.

Efter ytterligare några månaders studier upptäckte jag att enstaka hängningar inträffar när antingen cachen förbrukar allt på servern och inget ledigt utrymme finns kvar eller det finns ett ledigt minne, men mindre än 1 GB RAM eller MS SQL Server-tjänsten upptar allt tilldelat RAM-minne (via Task Manager). Men den andra händelsen inträffade bara två gånger per hela studien.

Faktum är att bokstavligen allt skrivs in i cachen, medan cachen inte alltid släpps i tid. Problemet med cachen löstes med programmet EmptyStandbyList.exe.

Jag konfigurerade den här applikationen via Task Scheduler för att köras 1 gång varje timme. Efter allt arbete som utförts har det inte förekommit några frågestopp på alla objekt på mer än ett halvår nu.

Det enda som förblir oklart är de sällsynta fallen när en fråga lägger på i 5-10 sekunder en gång i månaden en slumpmässig dag och vid en slumpmässig tidpunkt. Det fanns 4 sådana fall och endast på två objekt under ett halvår när MS SQL Server-tjänsten upptar allt tilldelat minne under en kort tidsperiod.

I grund och botten finns det ingen anledning att gräva djupare, eftersom användare inte märker några avbrott och allt fungerar bra, men om någon har några tankar är jag tacksam för att dela med mig.

Den här artikeln skrevs för att hjälpa dem som stöter på sådana problem, eftersom jag inte hittade ett heltäckande svar på Internet och jag ägnade mycket tid åt att studera problemet och hitta lösningen.

Se även:

  1. Implementering av SQL Server Performance Indicator för frågor, lagrade procedurer och utlösare
  2. Automatisk indexdefragmentering i MS SQL Server Database


Användbart verktyg:

dbForge Query Builder för SQL Server – tillåter användare att snabbt och enkelt bygga komplexa SQL-frågor via ett intuitivt visuellt gränssnitt utan manuell kodskrivning.


  1. Hur man ändrar datumformat i Oracle-databasen

  2. Fixa "Minst ett av argumenten till COALESCE måste vara ett uttryck som inte är NULL-konstanten" i SQL Server

  3. Hur man släpper eller tar bort alla utlösare från en databas i SQL Server

  4. Komma igång Justera prestanda i Azure SQL Database