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

Cosa sta bloccando Seleziona i primi 1 * da TableName con (nolock) per restituire un risultato?

SELECT interrogazioni con NOLOCK in realtà non prendono serrature, hanno comunque bisogno di un SCH-S (stabilità dello schema) blocco sul tavolo (e poiché è un heap ci vorrà anche un hobt bloccare ).

Inoltre prima di SELECT può anche iniziare SQL Server deve compilare un piano per l'istruzione, che richiede anche di prendere un SCH-S bloccati sul tavolo.

Poiché la tua transazione di lunga durata crea la tabella tramite SELECT ... INTO contiene un SCH-M incompatibile bloccalo fino al completamento dell'istruzione.

Puoi verificarlo cercando in sys.dm_os_waiting_tasks mentre mentre durante il periodo di blocco.

Quando ho provato quanto segue in una connessione

BEGIN TRAN

SELECT *
INTO NewT
FROM master..spt_values

/*Remember to rollback/commit this later*/

E quindi eseguire (o semplicemente provare a visualizzare il piano di esecuzione stimato)

SELECT *
FROM NewT
WITH (NOLOCK)

in un secondo la query di lettura è stata bloccata.

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

Mostra che il tipo di attesa è effettivamente SCH_S e la risorsa di blocco 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