sql >> Database >  >> RDS >> Sqlserver

SQL-impasses vermijden met het afstemmen van zoekopdrachten:advies van Brent Ozar

Als onderdeel van Quest's Database Training Days Fall Series, presenteerde Brent Ozar, Microsoft Certified Master een tutorial over "Avoiding Deadlocks with Query Tuning". Het programma richtte zich op de drie gelijktijdigheidsproblemen die zich voordoen in SQL Server, drie manieren om ze op te lossen en een manier die ze lijkt op te lossen, maar dat in werkelijkheid niet doet.

Gelijktijdigheidsproblemen:vergrendelen, blokkeren en deadlocks in SQL Server

Wat zijn gelijktijdigheidsproblemen? Ze treden op wanneer query's conflicten met elkaar over database-objecten zoals tabellen proberen te vermijden. Dit zijn:

  • Vergrendelen – Query's doen dit de hele tijd om te voorkomen dat andere query's tegelijkertijd een tabel gebruiken. Dit is een normale databasebewerking.
  • Blokkeren  – Dit gebeurt wanneer een zoekopdracht een normale vergrendeling heeft, maar een andere zoekopdracht dezelfde vergrendeling probeert te verkrijgen. De tweede query moet zo lang wachten als nodig is voordat de eerste query de vergrendeling opheft. Afhankelijk van de aard van de eerste vraag, kan de tweede zeer korte of zeer lange tijd wachten. Het zijn die lange wachttijden die de prestaties echt beïnvloeden.
  • Deadlocking – Deadlocks treden op wanneer de ene zoekopdracht een vergrendeling krijgt, een andere zoekopdracht een andere vergrendeling en vervolgens de vergrendeling van de ander wil verkrijgen. SQL Server lost dit op door een van de query's aan te wijzen als het slachtoffer en deze te doden om de impasse te doorbreken. Ook al kan een van de zoekopdrachten doorgaan, dit heeft ook invloed op de prestaties.

Gelijktijdigheidsproblemen oplossen

Er zijn manieren om gelijktijdigheidsproblemen op te lossen, ongeacht of u blokkades of impasses ervaart in SQL Server. Brent presenteerde deze drie methoden en besteedde het grootste deel van de rest van de sessie aan de tweede - het repareren van slechte code.

  1. Beschik over voldoende indexen om uw zoekopdrachten snel te maken, maar niet zo veel dat ze de zaken vertragen doordat zoekopdrachten meer vergrendelingen voor langere tijd vasthouden
  2. Stel uw transactiecode zo af dat zoekopdrachten elke keer in dezelfde voorspelbare volgorde door tabellen werken
  3. Gebruik het juiste isolatieniveau voor de behoeften van uw toepassing

Terwijl hij in het hands-on deel van het programma sprong, merkte Brent op over het gebruik van NOLOCK-statements voor blokkering en deadlocking. Hij waarschuwde dat NOLOCK deze problemen niet echt oplost omdat het afhankelijk is van "dirty reads" - in wezen negeert het de rijvergrendelingen van andere query's.

In zijn demonstratie hiervan met behulp van de Stack Overflow-database, creëerde hij een eenvoudige query die mensen met de naam "Alex" zocht en telde. Vervolgens maakte hij een andere zoekopdracht die een update zou uitvoeren voor mensen die niet . zijn genaamd Alex - geen toevoegingen of verwijderingen van records. De ene vraag zou niets met de andere te maken moeten hebben. Maar als ze samen worden uitgevoerd, leidt dit tot verschillende resultaten in het aantal mensen met de naam Alex. Dit komt omdat NOLOCK u gegevens laat zien die niet zijn vastgelegd, wat leidt tot willekeurige resultaten die u niet kunt voorspellen. Het gebeurt alleen onder gelijktijdigheid.

Het is duidelijk dat er een betere oplossing nodig is voor blokkering en deadlocking in SQL Server die niet leidt tot willekeurige en onvoorspelbare resultaten.

Een betere oplossing voor SQL-impasses

Brent demonstreerde vervolgens hoe je een impasse oplost door de code te veranderen die de impasse veroorzaakt. Zijn eerste demo toonde een eenvoudige situatie met twee tafels, zodat het publiek in slow motion een impasse kon zien terwijl het gebeurde. Omdat SQL Server elke 5 seconden naar deadlocks zoekt en de query doodt die het gemakkelijkst terug te draaien is, konden we het slachtoffer van de deadlock zien opduiken.

In een eenvoudige situatie is het meest algemene advies van toepassing, en dat is om de tabellen elke keer in dezelfde volgorde aan te raken bij het maken van query's. Dit zorgt er over het algemeen voor dat zoekopdrachten elkaar niet in een impasse raken.

Hoe zit het met complexere vragen? Voor dit scenario gebruikte Brent een meer realistische situatie die zich gemakkelijk zou kunnen voordoen op Stack Overflow, waar twee mensen elkaars vragen upvoten. Omdat bij beide transacties dezelfde gebruikers betrokken zijn, ontstaat er een impasse.

Hier is het niet voldoende om elke tafel elke keer in dezelfde volgorde te doorlopen, maar het is ook noodzakelijk om het aantal keren dat elke tafel wordt aangeraakt te minimaliseren. Zoals Brent het uitlegde, kan de oplossing een lelijke code bevatten die ervoor zorgt dat de zoekopdrachten worden geblokkeerd, maar in ieder geval niet in een impasse. In dit geval is een blokkering van korte duur waarmee beide zoekopdrachten kunnen worden voltooid, beter dan een impasse die een van beide beëindigt.

Niemand wil code veranderen in honderden zoekopdrachten, dus focus op degenen die constant vastlopen, verwijder onnodige regels uit de transactie en wees niet bang om een ​​blokkering in te voeren om een ​​impasse te voorkomen.


  1. Database kopiëren/dupliceren zonder mysqldump

  2. MySQL-weergaven maken en gebruiken

  3. Zoeken in volledige tekst sinds PostgreSQL 8.3

  4. Hoe een primaire sleutel in SQL te verwijderen