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

Fejlfinding af langvarige forespørgsler i MS SQL Server

Forord

Der er et informationssystem, som jeg administrerer. Systemet består af følgende komponenter:

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

Disse informationssystemer er installeret på flere objekter. Informationssystemet bruges aktivt 24 timer i døgnet af 2 til 20 brugere på én gang på hvert objekt. Derfor kan du ikke udføre rutinemæssig vedligeholdelse på én gang. Så jeg er nødt til at «sprede» SQL Server-indeksdefragmentering i løbet af dagen, i stedet for at defragmentere alle de nødvendige fragmenterede indekser på én gang. Dette gælder også for andre operationer.

Egenskaben for statistik auto-opdatering er indstillet i databasens egenskaber. Desuden er statistikken opdateret på det defragmenterede indeks.

Problem

For omkring et år siden stødte jeg på følgende problem:

Fra tid til anden kørte alle forespørgsler langsomt. Især var forsinkelsestiden tilfældig. Det skete på hver genstand på en tilfældig dag. Desuden, da jeg begyndte at analysere, hvor ofte forsinkelserne opstår (ved hjælp af profileren), fandt jeg ud af, at de opstår hver dag på et tilfældigt tidspunkt. Brugerne er bare ikke altid opmærksomme på dem, men tager dem som den eneste tilfældige forsinkelse, og så fungerer systemet hurtigt igen.

Løser problemet

Jeg har gennemgået alle de langsomt kørende forespørgsler. Det mærkeligste var, at alle forespørgsler kørte langsomt på et tilfældigt tidspunkt, selv de simpleste, som at trække den sidste post fra en tabel med flere tusinde rækker.

Yderligere udførte jeg følgende trin:

1. Jeg analyserede MS SQL Server- og Windows Server-logfiler, men kunne ikke finde årsagen til forsinkelser.
2. Jeg analyserede indekser (fragmentering osv.), tilføjede de manglende og fjernede ubrugte.
3. Jeg analyserede forespørgslerne – nogle forespørgsler blev forbedret.
4. Jeg analyserede opgaverne i SQL Agent og kunne ikke forbinde opgaverne med forsinkelsesproblemet.
5. Jeg analyserede opgaverne i Task Scheduler og kunne ikke forbinde opgaverne med forsinkelsesproblemet.
6. Profiler viste resultaterne, men ikke årsagen til forsinkelser.
7. Jeg foretog en kontrol for dødvande – ingen lange blokeringer blev afsløret.

Som et resultat brugte jeg mere end 3 måneder på den mislykkede søgning efter årsagen til lejlighedsvise langsomt kørende forespørgsler. Jeg afslørede dog en interessant kendsgerning - i stedet for Worker-udførelsesindikatoren steg indikatoren for forløbet ventetid for alle forespørgslerne. Dette faktum gav mig ideen om, at der er noget galt med diskene. Jeg tjekkede dem – alt var i orden.

Løsning

Til min overraskelse afslørede jeg ved et uheld, at når en forespørgsel blev udført langsomt i applikationen, kørte den hurtigt i SSMS. En artikel hjalp med at løse problemet (den foreslog i det mindste ideen).

Et afsnit fra artiklen:

I praksis er den vigtigste SET-indstilling ARITHABORT, fordi standardværdien for denne indstilling er forskellig for applikationer og for SQL Server Management Studio. Dette forklarer, hvorfor du kan registrere en langsomt kørende forespørgsel i din applikation og derefter få god hastighed ved at udføre den i SSMS. Applikationen bruger en plan, der er bygget til et sæt værdier, der adskiller sig fra de faktiske korrekte værdier. Hvorimod hvis du kører forespørgslen i SSMS, er det højst sandsynligt, at cachen endnu ikke har en eksekveringsplan for ARITHABORT ON, og derfor vil SQL Server bygge en plan for dine nuværende værdier.

Forskellen i udførelse skyldtes parameteren SET ARITHABORT. For alle forespørgsler udført i SSMS er denne mulighed aktiveret, og for forespørgsler udefra (fra applikationer) - deaktiveret. Det kan ikke aktiveres, selv ved en simpel forespørgsel til applikationer:

SET ARITHABORT ON;

En skør ide fulgte - rydde proceduremæssig cache på tidspunktet for afbrydelsen.

Til den efterfølgende manuelle kontrol skal jeg skrive følgende erklæring før forespørgslen i SSMS:

SET ARITHABORT OFF;

Således vil vi simulere applikationens drift. Da forespørgslen havde kørt i lang tid, ryddede jeg den proceduremæssige cache. Og det hjalp altid. Før rydning af procedurecachen, kunne forespørgslen køre op til 20-30 sekunder og bagefter – 0 sekunder.

Derefter udførte jeg endnu et eksperiment – ​​rensede hele procedurecachen for hele databasen hver time via SQL Agent:

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

Derefter kørte alle forespørgsler meget hurtigt (mindre end 0,05 sekunder). Der var kun nogle forekomster på op til 5-10 sekunders udførelse, men brugerne bemærkede ikke nogen afbrydelser. Desuden forbedrede opdateringen af ​​statistikkerne ikke resultaterne, så jeg deaktiverede statistikopdateringen.

Efter et par måneders undersøgelse opdagede jeg, at der lejlighedsvis opstår afbrydelser, når enten cachen optager alt på serveren, og der ikke er ledig plads tilbage, eller der er en ledig hukommelse, men mindre end 1 GB RAM eller MS SQL Server-tjenesten optager al den tildelte RAM (via Task Manager). Men den anden hændelse fandt kun sted to gange i hele undersøgelsen.

Faktum er, at bogstaveligt talt alt er skrevet ind i cachen, mens cachen ikke altid frigives til tiden. Problemet med cachen blev løst ved hjælp af EmptyStandbyList.exe-programmet.

Jeg konfigurerede denne applikation via Task Scheduler til at køre 1 gang hver time. Efter alt det udførte arbejde er der ingen forespørgsler lagt på på alle objekter i mere end et halvt år nu.

Det eneste, der forbliver uklart, er de sjældne tilfælde, hvor en forespørgsel lægger på i 5-10 sekunder en gang om måneden på en tilfældig dag og på et tilfældigt tidspunkt. Der var 4 sådanne tilfælde og kun på to objekter i et halvt år, hvor MS SQL Server-tjenesten optager al den tildelte hukommelse i en kort periode.

Grundlæggende er der ingen grund til at grave dybere, da brugerne ikke bemærker nogen afbrydelser, og alt fungerer fint, men hvis nogen har nogle tanker, vil jeg være taknemmelig for at dele.

Denne artikel er skrevet for at hjælpe dem, der støder på sådanne problemer, da jeg ikke fandt et udtømmende svar på internettet, og jeg brugte meget tid på at studere problemet og finde løsningen.

Se også:

  1. Implementering af SQL Server Performance Indicator for forespørgsler, lagrede procedurer og triggere
  2. Automatisk indeksdefragmentering i MS SQL Server-database


Nyttigt værktøj:

dbForge Query Builder til SQL Server – giver brugerne mulighed for hurtigt og nemt at bygge komplekse SQL-forespørgsler via en intuitiv visuel grænseflade uden manuel kodeskrivning.


  1. Postgres fejler med 'could not open relation mapping file global/pg_filenode.map'

  2. Flyt SQL-data fra en tabel til en anden

  3. MySQL – Ret fejl – WordPress-databasefejl Duplikatindtastning for nøgle PRIMÆR for forespørgsel INSERT INTO wp_options

  4. Erstat unicode-tegn i PostgreSQL