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

Hvad blokerer Vælg top 1 * fra Tabelnavn med (nolock) fra at returnere et resultat?

SELECT forespørgsler med NOLOCK tag faktisk ikke nogen låse, de har stadig brug for en SCH-S (skemastabilitet) lås på bordet (og da det er en heap det vil også tage en hobt lås ).

Derudover før SELECT kan endda begynde SQL Server skal kompilere en plan for sætningen, som også kræver, at den tager en SCH-S lock out på bordet.

Da din langvarige transaktion opretter tabellen via SELECT ... INTO den har en inkompatibel SCH-M lås på den, indtil erklæringen er færdig.

Du kan bekræfte dette ved at se i sys.dm_os_waiting_tasks mens mens i blokeringsperioden.

Da jeg prøvede følgende i én forbindelse

BEGIN TRAN

SELECT *
INTO NewT
FROM master..spt_values

/*Remember to rollback/commit this later*/

Og så udfører (eller bare prøver at se den estimerede udførelsesplan)

SELECT *
FROM NewT
WITH (NOLOCK)

på et sekund blev læseforespørgslen blokeret.

SELECT wait_type,
       resource_description
FROM sys.dm_os_waiting_tasks
WHERE session_id = <spid_of_waiting_task>

Viser, at ventetypen faktisk er SCH_S og blokeringsressourcen SCH-M

wait_type        resource_description
---------------- -------------------------------------------------------------------------------------------------------------------------------
LCK_M_SCH_S      objectlock lockPartition=0 objid=461960722 subresource=FULL dbid=1 id=lock4a8a540 mode=Sch-M associatedObjectId=461960722


  1. SQL-forespørgselsfelter som kolonner

  2. Hvornår skal SQL_NO_CACHE bruges

  3. Oracle Trigger på indlejret bord

  4. Fejlfinding af disk I/O-flaskehalse