Voorwoord
Er is een informatiesysteem dat ik beheer. Het systeem bestaat uit de volgende componenten:
1. MS SQL Server-database
2. Servertoepassing
3. Clienttoepassingen
Deze informatiesystemen zijn op meerdere objecten geïnstalleerd. Het informatiesysteem wordt 24 uur per dag actief gebruikt door 2 tot 20 gebruikers tegelijk op elk object. Daarom kunt u routineonderhoud niet in één keer uitvoeren. Ik moet dus de defragmentatie van de SQL Server-index over de dag "verspreiden", in plaats van alle noodzakelijke gefragmenteerde indexen in één keer te defragmenteren. Dit geldt ook voor andere bewerkingen.
De eigenschap voor automatisch bijwerken van statistieken wordt ingesteld in de eigenschappen van de database. Bovendien worden de statistieken bijgewerkt op de gedefragmenteerde index.
Probleem
Ongeveer een jaar geleden kwam ik het volgende probleem tegen:
Van tijd tot tijd waren alle zoekopdrachten traag. Met name de vertragingstijd was willekeurig. Het gebeurde op elk object op een willekeurige dag. Bovendien, toen ik begon te analyseren hoe vaak de vertragingen voorkomen (met behulp van de profiler), ontdekte ik dat ze elke dag op een willekeurig tijdstip voorkomen. Gebruikers letten er gewoon niet altijd op, maar beschouwen ze als de enige willekeurige vertraging, en dan werkt het systeem weer snel.
Het probleem oplossen
Ik heb alle traag lopende zoekopdrachten bekeken. Het vreemdste was dat alle zoekopdrachten op een willekeurig tijdstip traag verliepen, zelfs de eenvoudigste, zoals het laatste record uit een tabel met enkele duizenden rijen.
Verder heb ik de volgende stappen uitgevoerd:
1. Ik heb de logbestanden van MS SQL Server en Windows Server geanalyseerd, maar kon de oorzaak van de vertragingen niet vinden.
2. Ik analyseerde indexen (fragmentatie, enz.), voegde de ontbrekende toe en verwijderde ongebruikte.
3. Ik heb de zoekopdrachten geanalyseerd – sommige zoekopdrachten zijn verbeterd.
4. Ik analyseerde de taken in SQL Agent en kon de taken niet associëren met het vertragingsprobleem.
5. Ik analyseerde de taken in Taakplanner en kon de taken niet associëren met het vertragingsprobleem.
6. Profiler liet de resultaten zien, maar niet de oorzaak van vertragingen.
7. Ik heb een controle uitgevoerd op deadlocks - er werden geen lange blokkades onthuld.
Als gevolg hiervan heb ik meer dan 3 maanden besteed aan de mislukte zoektocht naar de reden van af en toe traag lopende zoekopdrachten. Ik onthulde echter een interessant feit:in plaats van de Worker-uitvoeringsindicator nam de Elapsed wait-indicator toe voor alle vragen. Dit feit gaf me het idee dat er iets mis is met de schijven. Ik heb ze gecontroleerd - alles was in orde.
Oplossing
Tot mijn verbazing onthulde ik per ongeluk dat wanneer een query langzaam werd uitgevoerd in de toepassing, deze snel werd uitgevoerd in SSMS. Eén artikel hielp bij het oplossen van het probleem (het suggereerde tenminste het idee).
Een alinea uit het artikel:
In de praktijk is de belangrijkste SET-optie ARITHABORT, omdat de standaardwaarde voor deze optie anders is voor applicaties en voor SQL Server Management Studio. Dit verklaart waarom u een traag lopende query in uw toepassing kunt detecteren en vervolgens een goede snelheid kunt krijgen door deze in SSMS uit te voeren. De applicatie maakt gebruik van een plan dat is gebouwd voor een set waarden die afwijkt van de daadwerkelijke juiste waarden. Terwijl als u de query uitvoert in SSMS, de cache hoogstwaarschijnlijk nog geen uitvoeringsplan voor ARITHABORT ON heeft, en daarom zal SQL Server een plan maken voor uw huidige waarden.
Het verschil in uitvoering was te wijten aan de parameter SET ARITHABORT. Voor alle query's die in SSMS worden uitgevoerd, is deze optie ingeschakeld en voor query's van buitenaf (van toepassingen) - uitgeschakeld. Het kan niet worden ingeschakeld, zelfs niet door een eenvoudige aanvraag voor toepassingen:
SET ARITHABORT ON;
Er volgde een gek idee - procedurele cache wissen op het moment van ophangen.
Voor de daaropvolgende handmatige controle moet ik de volgende verklaring voor de query in SSMS schrijven:
SET ARITHABORT OFF;
Zo zullen we de werking van de applicatie simuleren. Toen de query al lang aan de gang was, heb ik de procedurecache gewist. En dit hielp altijd. Voordat de procedurecache wordt gewist, kan de query 20-30 seconden duren en daarna 0 seconden.
Daarna voerde ik nog een experiment uit – het opschonen van de volledige procedurele cache voor de hele database elk uur via SQL Agent:
--cleaning the cache by database id DBCC FLUSHPROCINDB (@db_id);
Daarna verliepen alle zoekopdrachten zeer snel (minder dan 0,05 seconden). Er waren slechts enkele gevallen van uitvoering tot 5-10 seconden, maar gebruikers merkten geen vastlopers op. Bovendien verbeterde het bijwerken van de statistieken de resultaten niet, dus heb ik de update van de statistieken uitgeschakeld.
Na nog een paar maanden studie ontdekte ik dat er af en toe vastloopt wanneer de cache alles op de server verbruikt en er geen vrije ruimte meer is of er is een vrij geheugen, maar minder dan 1 GB RAM of de MS SQL Server-service neemt al het toegewezen RAM-geheugen in beslag (via Taakbeheer). Maar de tweede gebeurtenis vond slechts twee keer plaats per het hele onderzoek.
Feit is dat letterlijk alles in de cache wordt geschreven, terwijl de cache niet altijd op tijd wordt vrijgegeven. Het probleem met de cache is opgelost met het programma EmptyStandbyList.exe.
Ik heb deze applicatie via Taakplanner geconfigureerd om 1 keer per uur uit te voeren. Nadat al het werk is volbracht, zijn er al meer dan een half jaar geen vragen meer over alle objecten.
Het enige dat onduidelijk blijft, zijn de zeldzame gevallen waarin een query eenmaal per maand 5-10 seconden op een willekeurige dag en op een willekeurig tijdstip vastloopt. Er waren 4 van dergelijke gevallen en slechts op twee objecten gedurende een half jaar wanneer de MS SQL Server-service al het toegewezen geheugen voor een korte periode in beslag neemt.
In principe is het niet nodig om dieper te graven, omdat gebruikers geen vastlopers opmerken en alles goed werkt, maar als iemand een mening heeft, zal ik het op prijs stellen om het te delen.
Dit artikel is geschreven om diegenen te helpen die dergelijke problemen tegenkomen, aangezien ik geen alomvattend antwoord op internet heb gevonden en ik veel tijd heb besteed aan het bestuderen van het probleem en het vinden van de oplossing.
Zie ook:
- Implementatie van SQL Server-prestatie-indicator voor query's, opgeslagen procedures en triggers
- Automatisering van indexdefragmentatie in MS SQL Server-database
Handig hulpmiddel:
dbForge Query Builder voor SQL Server – stelt gebruikers in staat om snel en eenvoudig complexe SQL-query's te bouwen via een intuïtieve visuele interface zonder handmatig code schrijven.