sql >> Database >  >> RDS >> Sqlserver

SQL-impasse met selectie-/updatebewerkingen op een tabel

De twee query's die de impasse veroorzaken, zijn de SELECT hieronder (process id="process3980de4558" ):

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

En de UPDATE onderstaande vraag (process id="process386ed48188" ):

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

De <resource-list> sectie noteert de SELECT query bezat een exclusieve (X) vergrendeling op een pagina en probeerde een intent-shared (IS) vergrendeling op een andere pagina te verkrijgen terwijl deze gegevens aan het lezen was. De UPDATE query had al een IS-vergrendeling en probeerde een X-vergrendeling op een pagina te verkrijgen om de update uit te voeren.

Gezien de join tegen deze tafel:

...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...

De SELECT query is al eigenaar van een exclusief slot. Dit betekent waarschijnlijk dat het onderdeel is van een grotere transactie die al een UPDATE . heeft uitgevoerd in een eerdere vraag. Vergrendelingen van eerdere zoekopdrachten worden gehandhaafd om de gegevensintegriteit tijdens de transactie te behouden (afhankelijk van de transactie-isolatieniveau ).

De UPDATE query moet de tabel lezen tbl_Ref_Attr_Prod_team . Het verwerft intentie-gedeelde vergrendelingen op pagina's en rijen tijdens het lezen van gegevens. Wanneer de UPDATE query de overeenkomende rijen vindt, zal het proberen de IS-sloten om te zetten in X-sloten. IS-sloten zijn niet compatibel met X-sloten. Omdat de SELECT query heeft al een IS-vergrendeling op een of meer van die pagina's, de query's lopen vast met elkaar.

Een mogelijke oorzaak is het ontbreken van indexen op tbl_Ref_Attr_Prod_team.prod_key . Zonder een index op deze kolom, de UPDATE query scant alle rijen in de tabel tbl_Ref_Attr_Prod_team .

Zelfs als er een index bestaat op prod_key , als er een klein aantal rijen in de tabel is, kan SQL Server besluiten dat de prestaties beter zijn als de query de hele tabel scant in plaats van de index te zoeken. Het opnemen van het zoekplan wanneer de impasse zich voordoet, zou deze theorie bevestigen.

We komen regelmatig deadlocks tegen in kleine tabellen bij het opzetten van nieuwe databases. Aanvankelijk zijn de tabellen klein en veroorzaken tafelscans allerlei impasses. Later, wanneer de tabellen groter zijn, zijn de berekende kosten voor het scannen van de tabel hoger dan de kosten voor het zoeken naar de index, en de impasses treden niet meer op. In testomgevingen waar het aantal rijen altijd klein is, hebben we onze toevlucht genomen tot het gebruik van FORESEEK en WITH INDEX hints om indexzoekacties te forceren in plaats van scans. We kijken ernaar uit om queryplannen te kunnen forceren via de query store-functie van SQL Server 2016.




  1. kon driverfout niet vinden bij gebruik van PDO met MSSQL-server

  2. Hoe een ADDM-taak te maken en het rapport ervan te controleren

  3. PHP:het ophalen van afbeeldingen van MySQL Blob rechtstreeks in de <img>-tag

  4. Snelste manier om dezelfde query meerdere keren uit te voeren in SQL Server