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

SQL-deadlock med valg/opdateringsoperationer på en tabel

De to forespørgsler, der forårsager dødvandet, er SELECT nedenfor (process id="process3980de4558" ):

select @existing = team_it_cube_attr_05 from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key

Og UPDATE forespørgsel nedenfor (process id="process386ed48188" ):

UPDATE D
SET D.team_rss_attr_01 = LEFT(S.mkt_prodchar_13,25)...

<resource-list> sektionen noterer SELECT forespørgslen ejede en eksklusiv (X) lås på en side og forsøgte at erhverve en hensigtsdelt (IS) lås på en anden side, mens den læste data. UPDATE forespørgslen ejede allerede en IS-lås og forsøgte at erhverve en X-lås på en side for at udføre opdateringen.

Givet joinforbindelsen mod denne tabel:

...from tbl_Ref_Attr_Prod_Team where prod_id = @rec_key...
...INNER JOIN tbl_Ref_Attr_Prod_Team D ON D.prod_key=P.prod_key...

SELECT query ejer allerede en eksklusiv lås. Dette betyder sandsynligvis, at det er en del af en større transaktion, der allerede har udført en UPDATE i en tidligere forespørgsel. Låse fra tidligere forespørgsler vil blive opretholdt for at bevare dataintegriteten under transaktionen (afhængigt af transaktionsisoleringsniveau ).

UPDATE forespørgslen skal læse tabellen tbl_Ref_Attr_Prod_team . Den opretter hensigtsdelte låse på sider og rækker, mens den læser data. Når UPDATE forespørgslen finder de matchende rækker, vil den forsøge at konvertere IS-låsene til X-låse. IS-låse er ikke kompatible med X-låse. Fordi SELECT forespørgslen har allerede en IS-lås på en eller flere af disse sider, forespørgslerne går i stå med hinanden.

En mulig årsag ville være manglende indekser på tbl_Ref_Attr_Prod_team.prod_key . Uden et indeks på denne kolonne er UPDATE forespørgslen vil scanne alle rækkerne i tabellen tbl_Ref_Attr_Prod_team .

Også selvom der findes et indeks på prod_key , hvis der er et lille antal rækker i tabellen, kan SQL Server beslutte, at ydeevnen ville være bedre, hvis forespørgslen scannede hele tabellen i stedet for at søge indekset. Registrering af forespørgselsplanen, når dødvandet opstår, ville bekræfte denne teori.

Vi støder jævnligt på små fastlåste tabeller, når vi opretter nye databaser. I starten er bordene små, og bordscanninger forårsager alle mulige dødvande. Senere, når tabellerne er større, overstiger de beregnede omkostninger ved at scanne tabellen omkostningerne ved at søge efter indekset, og dødvande opstår ikke længere. I testmiljøer, hvor antallet af rækker er evigt lille, har vi tyet til at bruge FORESEEK og WITH INDEX tip til at tvinge indekssøgninger i stedet for scanninger. Vi ser frem til at kunne gennemtvinge forespørgselsplaner via forespørgselslagerfunktionen i SQL Server 2016.




  1. SQL-sætning - SQL Matrix

  2. Hvordan ser du ALT tekst fra en ntext eller nvarchar(max) i SSMS?

  3. URL-omskrivning med .htaccess lav dublerede mysql-indgange

  4. Hvad er standardnavnet i MySQL?