Nota
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare ad accedere o modificare le directory.
L'accesso a questa pagina richiede l'autorizzazione. È possibile provare a modificare le directory.
Si applica a: SQL Server 2025 (17.x)
Database SQL di Azure
Istanza gestita di SQL di Azure
database SQL in Microsoft Fabric
Il blocco ottimizzato offre un meccanismo di blocco delle transazioni migliorato per ridurre il blocco tra serrature e il consumo di memoria delle serrature per le transazioni simultanee.
Che cos'è il blocco ottimizzato?
Il blocco ottimizzato consente di ridurre la memoria di blocco poiché vengono mantenuti pochissimi blocchi anche per le transazioni di grandi dimensioni. Inoltre, il blocco ottimizzato evita le escalation di blocchi e può evitare determinati tipi di deadlock. In questo modo è possibile accedere simultaneamente alla tabella.
Il blocco ottimizzato è costituito da due componenti principali: blocco ID transazione (TID) e blocco dopo qualificazione (LAQ).
- Un ID transazione (TID) è un identificatore univoco di una transazione. Ogni riga viene contrassegnata dall'ultimo TID che lo ha modificato. Anziché blocchi potenzialmente numerosi di chiavi o identificatori di riga, viene usato un singolo blocco sul TID per proteggere tutte le righe modificate. Per altre informazioni, vedere blocco ID transazione (TID).
- Il blocco dopo qualificazione (LAQ) è un'ottimizzazione che valuta i predicati di una query in base alla versione della riga di cui è stato eseguito il commit più recente senza acquisire un blocco, migliorando così la concorrenza. LAQ richiede l'isolamento dello snapshot read committed (RCSI). Per altre informazioni, vedere la sezione relativa al blocco dopo qualificazione (LAQ).
Per esempio:
- Senza un blocco ottimizzato, l'aggiornamento di 1.000 righe in una tabella potrebbe richiedere 1.000 blocchi di riga esclusivi (
X) mantenuti fino alla fine della transazione. - Con il blocco ottimizzato, l'aggiornamento di 1.000 righe in una tabella potrebbe richiedere 1.000
Xblocchi di riga, ma ogni blocco viene rilasciato non appena ogni riga viene aggiornata e viene mantenuto unXsolo blocco TID fino alla fine della transazione. Poiché i blocchi vengono rilasciati rapidamente, l'utilizzo della memoria di blocco viene ridotto e l'escalation dei blocchi è molto meno probabile, migliorando la concorrenza del carico di lavoro.
Note
L'abilitazione del blocco ottimizzato riduce o elimina i blocchi di riga e di pagina acquisiti dalle istruzioni di Data Modification Language (DML) ad esempio INSERT, UPDATE, DELETE. MERGE Non ha alcun effetto su altri tipi di blocchi di database e oggetti, ad esempio blocchi dello schema.
Availability
La tabella seguente riepiloga la disponibilità e lo stato abilitato del blocco ottimizzato tra piattaforme SQL.
| Platform | Available | Abilitato per impostazione predefinita |
|---|---|---|
| Database SQL di Microsoft Azure | Yes | Sì (sempre abilitato) |
| Database SQL su Microsoft Fabric | Yes | Sì (sempre abilitato) |
| Istanza gestita di SQL di AzureAUTD | Yes | Sì (sempre abilitato) |
| Istanza gestita di SQL di Azure2025 | Yes | Sì (sempre abilitato) |
| Istanza gestita di SQL di Azure2022 | No | N/A |
| SQL Server 2025 (17.x) | Yes | No (può essere abilitato per ogni database) |
| SQL Server 2022 (16.x) e versioni precedenti | No | N/A |
Abilitare e disabilitare
Per abilitare o disabilitare il blocco ottimizzato per un database di SQL Server, usare il ALTER DATABASE ... SET OPTIMIZED_LOCKING = ON | OFF comando . Per altre informazioni, vedere le opzioni ALTER DATABASE SET.
Il blocco ottimizzato si basa su altre funzionalità del database:
- Prima di abilitare il blocco ottimizzato, è necessario abilitare il ripristino accelerato del database in un database. Viceversa, per disabilitare ADR, è necessario disabilitare prima di tutto il blocco ottimizzato se è abilitato.
- Per sfruttare al meglio i vantaggi offerti dal blocco ottimizzato, è necessario abilitare read committed snapshot isolation (RCSI) per il database. Il componente LAQ del blocco ottimizzato è attivo solo se RCSI è abilitato.
AdR è sempre abilitato nel database SQL di Azure, nell'istanza gestita di SQL di Azure e nel database SQL in Microsoft Fabric. RCSI è abilitato per impostazione predefinita nel database SQL di Azure e nel database SQL in Microsoft Fabric.
Per verificare che queste opzioni siano abilitate per il database corrente, collegarsi al database e usare la query T-SQL seguente:
SELECT database_id,
name,
is_accelerated_database_recovery_on,
is_read_committed_snapshot_on,
is_optimized_locking_on
FROM sys.databases
WHERE name = DB_NAME();
Il blocco ottimizzato è abilitato?
Il blocco ottimizzato è abilitato per ogni database. Connettersi al database e usare la query seguente per verificare se il blocco ottimizzato è abilitato:
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn') AS is_optimized_locking_enabled;
| Result | Description |
|---|---|
0 |
Il blocco ottimizzato è disabilitato. |
1 |
Il blocco ottimizzato è abilitato. |
NULL |
Il blocco ottimizzato non è disponibile. |
È anche possibile usare la vista del catalogo sys.databases . Ad esempio, per verificare se il blocco ottimizzato è abilitato per tutti i database, eseguire la query seguente:
SELECT database_id,
name,
is_optimized_locking_on
FROM sys.databases;
Panoramica del sistema di blocco
Questo è un breve riepilogo del comportamento quando il blocco ottimizzato non è abilitato. Per altre informazioni, vedere Guida per il controllo delle versioni delle righe e il blocco della transazione.
Nel motore di database, il blocco è un meccanismo che impedisce a più transazioni di aggiornare contemporaneamente gli stessi dati per garantire la ACID proprietà delle transazioni.
Quando una transazione deve modificare i dati, richiede un blocco sui dati. Il blocco viene concesso se non vengono mantenuti altri blocchi in conflitto sui dati e la transazione può procedere con la modifica. Se nei dati viene mantenuto un altro blocco in conflitto, la transazione deve attendere il rilascio del blocco prima di poter procedere.
Quando più transazioni tentano di accedere contemporaneamente agli stessi dati, il motore di database deve risolvere conflitti potenzialmente complessi con letture e scritture simultanee. Il blocco è uno dei meccanismi in base ai quali il motore può fornire la semantica per i livelli di isolamento delle transazioni SQL ANSI. Anche se il blocco nei database è essenziale, la riduzione della concorrenza, i deadlock, la complessità e il sovraccarico del blocco possono influire sulle prestazioni e sulla scalabilità.
Blocco dell'ID transazione (TID)
Quando sono in uso livelli di isolamento basati sul versioning delle righe o quando è abilitato l'ADR, ogni riga del database contiene internamente un ID di transazione (TID). TID viene salvato in modo permanente con la riga. Ogni transazione che modifica una riga contrassegna la riga con il relativo TID.
Con il blocco TID, invece di acquisire il blocco sulla chiave della riga, viene eseguito un blocco sul TID della riga. La transazione di modifica contiene un blocco X sul relativo TID. Altre transazioni acquisiscono un S blocco sul TID per attendere il completamento della prima transazione. Con il blocco TID, i blocchi di pagina e di riga continuano a essere acquisiti per le modifiche, ma tutte le pagine e blocchi di riga vengono rilasciati al completamento dell'aggiornamento di ciascuna riga. L'unico blocco mantenuto fino alla fine della transazione è il blocco X singolo sulla risorsa TID, sostituendo i blocchi multipli di pagina e di riga (chiave).
Si consideri l'esempio seguente che mostra i blocchi per la sessione corrente mentre è attiva una transazione di scrittura:
/* Is optimized locking is enabled? */
SELECT DATABASEPROPERTYEX(DB_NAME(), 'IsOptimizedLockingOn') AS is_optimized_locking_enabled;
CREATE TABLE t0
(
a int PRIMARY KEY,
b int NULL
);
INSERT INTO t0 VALUES (1,10),(2,20),(3,30);
GO
BEGIN TRANSACTION;
UPDATE t0
SET b = b + 10;
SELECT *
FROM sys.dm_tran_locks
WHERE request_session_id = @@SPID
AND
resource_type IN ('PAGE','RID','KEY','XACT');
COMMIT TRANSACTION;
GO
DROP TABLE IF EXISTS t0;
Se il blocco ottimizzato è abilitato, la richiesta contiene solo un singolo X blocco sulla XACT risorsa (di transazione).
Se il blocco ottimizzato non è abilitato, la stessa richiesta mantiene quattro blocchi: un blocco di intento esclusivo IX sulla pagina contenente le righe e tre blocchi chiave X su ogni riga.
La dmv (Dynamic Management View) sys.dm_tran_locks è utile per esaminare o risolvere i problemi di blocco. Qui viene utilizzato per osservare il blocco ottimizzato mentre è in funzione.
Blocco dopo la qualificazione (LAQ)
Basandosi sull'infrastruttura TID, il componente LAQ del blocco ottimizzato modifica il modo in cui le istruzioni DML come INSERT, UPDATE e DELETE acquisiscono i lock.
Senza il blocco ottimizzato, i predicati delle query vengono controllati riga per riga in uno scan, eseguendo prima un blocco di riga di aggiornamento (U). Se il predicato è soddisfatto, viene eseguito un blocco di riga esclusivo (X) prima di aggiornare la riga e mantenuto fino alla fine della transazione.
Con il blocco ottimizzato e quando il livello di isolamento dello snapshot (RCSI) è abilitato, i predicati possono essere controllati ottimisticamente sulla versione di cui è stato eseguito il READ COMMITTED commit più recente della riga senza eseguire alcun blocco. Se il predicato non soddisfa, la query passa alla riga successiva nell'analisi. Se il predicato è soddisfatto, viene eseguito un X blocco di riga per aggiornare la riga.
In altre parole, il blocco viene preso dopo la qualificazione della riga per la modifica. Il X blocco di riga viene rilasciato al completamento dell'aggiornamento di riga, prima della fine della transazione.
Poiché la valutazione del predicato viene eseguita senza acquisire blocchi, le query simultanee che modificano righe diverse non si bloccano tra loro.
Per esempio:
/* Confirm that optimized locking and read committed snapshot isolation (RCSI) are both enabled on this database. */
SELECT database_id,
name,
is_accelerated_database_recovery_on,
is_optimized_locking_on,
is_read_committed_snapshot_on
FROM sys.databases
WHERE name = DB_NAME();
CREATE TABLE t1
(
a int NOT NULL,
b int NULL
);
INSERT INTO t1
VALUES (1,10),(2,20),(3,30);
GO
| Sessione 1 | Sessione 2 |
|---|---|
BEGIN TRANSACTION;UPDATE t1SET b = b + 10WHERE a = 1; |
|
BEGIN TRANSACTION;UPDATE t1SET b = b + 10WHERE a = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Senza il blocco ottimizzato, la sessione 2 viene bloccata perché la sessione 1 contiene un U blocco nella sessione di riga 2 e deve essere aggiornata. Tuttavia, con il blocco ottimizzato, la sessione 2 non viene bloccata perché i blocchi U non vengono eseguiti e poiché nella versione di commit più recente della riga 1, la colonna a è uguale a 1, che non soddisfa la condizione della sessione 2.
LAQ viene eseguita ottimisticamente nella supposizione che una riga non venga modificata dopo il controllo del predicato. Se il predicato è soddisfatto e la riga non è stata modificata dopo il controllo del predicato, viene modificata dalla transazione corrente.
Poiché i U lucchetti non vengono acquisiti, una transazione concomitante potrebbe modificare la riga dopo che il predicato è stato valutato. Se è presente una transazione attiva che contiene un X blocco TID sulla riga, il motore di database attende il completamento. Se la riga è stata modificata dopo che il predicato è stato valutato in precedenza, il motore di database rivaluta (riqualifica) il predicato prima di modificare la riga. Se il predicato è ancora soddisfatto, la riga viene modificata.
La riqualificazione del predicato è supportata da un sottoinsieme degli operatori del motore di query. Se è necessaria la rivalutazione del predicato, ma il piano di query usa un operatore che non supporta la riqualificazione del predicato, il motore di database interrompe internamente l'elaborazione delle istruzioni e la riavvia senza LAQ. Quando si verifica un'interruzione di questo tipo, viene generato l'evento esteso lock_after_qual_stmt_abort.
Alcune istruzioni, ad esempio UPDATE istruzioni con assegnazione di variabili e istruzioni con la clausola OUTPUT , non possono essere interrotte e riavviate senza modificarne la semantica. Per tali dichiarazioni, LAQ non viene usato.
Nell'esempio seguente il predicato viene rivalutato perché un'altra transazione ha modificato la riga:
CREATE TABLE t3
(
a int NOT NULL,
b int NULL
);
INSERT INTO t3 VALUES (1,10),(2,20),(3,30);
GO
| Sessione 1 | Sessione 2 |
|---|---|
BEGIN TRANSACTION;UPDATE t3SET b = b + 10WHERE a = 1; |
|
BEGIN TRANSACTION;UPDATE t3SET b = b + 10WHERE a = 1; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Ignorare i blocchi di indice (SIL)
Con il blocco TID, i blocchi di riga esclusivi a breve durata (X) e i blocchi di pagina intenzionalmente esclusivi (IX) vengono utilizzati per modificare le righe. Quando si usano RCSI e LAQ, questi blocchi sono necessari solo se potrebbero essere presenti altre query che accedono alla riga e si prevede che siano stabili. Esempi di tali query sono quelli in esecuzione con i REPEATABLE READ livelli di isolamento oppure SERIALIZABLE usando i suggerimenti di blocco corrispondenti. Tali query sono note come query di blocco delle righe (RLQ).
Quando non sono presenti query RLQ che accedono a una riga, il motore di database può ignorare l'acquisizione di blocchi di riga e di pagina durante la modifica di una riga e usare solo un latch di pagina esclusivo. Questa ottimizzazione riduce il sovraccarico di blocco mantenendo la semantica delle transazioni ACID. Ignorare i blocchi di riga e di pagina, in particolare, consente alle transazioni di modificare un numero elevato di righe.
Attualmente, l'ottimizzazione SIL viene usata solo nei casi seguenti:
-
INSERTdichiarazioni sugli heap.-
IXi blocchi di pagina vengono ignorati.
-
-
UPDATEistruzioni su indici cluster, indici non clusterizzati e heap.-
IXi blocchi di pagina eXi blocchi di riga vengono ignorati.
-
L'ottimizzazione SIL non viene attualmente usata nei casi seguenti:
- Istruzioni.
DELETE -
UPDATEistruzioni sugli heap se la riga contiene puntatori di forwarding esistenti o se l'aggiornamento aggiunge nuovi puntatori di forwarding. - Se la riga modificata contiene colonne che usano i tipi di dati LOB, ad esempio
varchar(max),nvarchar(max)varbinary(max), ejson. - Per le righe nelle pagine che sono state suddivise nella stessa transazione.
Euristica LAQ
Come descritto in Lock after qualification (LAQ), quando viene usata LAQ, le istruzioni che usano operatori di query che non supportano la riqualificazione del predicato potrebbero essere riavviate internamente ed elaborate senza LAQ. In questo caso, il sovraccarico della rielaborazione potrebbe diventare significativo. Per ridurre al minimo l'overhead, il blocco ottimizzato usa un meccanismo di feedback euristico che disabilita LAQ se il sovraccarico supera le soglie.
Ai fini del meccanismo di feedback, il lavoro eseguito da un'istruzione viene misurato nel numero di letture logiche. Se il motore di database modifica una riga modificata da un'altra transazione dopo l'avvio dell'elaborazione dell'istruzione, il lavoro eseguito dall'istruzione viene considerato potenzialmente sprecato perché potrebbe essere necessario rielaborare l'istruzione.
Durante l'esecuzione delle istruzioni, il motore di database gestisce i dati di feedback LAQ che tengono traccia del lavoro potenzialmente sprecato, le occorrenze della rielaborazione delle istruzioni e il lavoro totale eseguito dalle istruzioni che potrebbero essere rielaborate.
LAQ è disabilitato se il rapporto tra il lavoro potenzialmente sprecato e il lavoro totale o il rapporto tra il numero di istruzioni rielaborate e il numero totale di istruzioni superano le rispettive soglie. Se entrambi questi rapporti scendono al di sotto delle soglie, LAQ viene riabilitato.
I dati di feedback LAQ vengono rilevati a due livelli:
Per un piano di query.
- Il motore di database avvia il rilevamento del feedback LAQ per un piano alla prima occorrenza della rielaborazione della query.
- Se una query viene acquisita in Query Store, anche il feedback LAQ viene acquisito in Query Store. Il motore di database usa questo feedback per mantenere la LAQ abilitata o disabilitata per il piano nel caso di riavvio del database.
- I piani di query con feedback LAQ acquisito hanno una riga con un valore corrispondente
plan_idnella vista del catalogo sys.query_store_plan_feedback . Lefeature_idcolonne efeature_descsono impostate rispettivamente su 4 eLAQ Feedback.
Per un database.
- Il feedback viene aggregato per tutte le istruzioni che non hanno feedback a livello di piano di query, ad esempio se una query non viene acquisita in Query Store.
- Il feedback viene rilevato dopo l'avvio del database e viene ricreato dopo ogni avvio.
Quando si decide se usare LAQ per un'istruzione, il sistema usa il feedback del piano di query, se disponibile. In caso contrario, usa il feedback a livello di database. Ciò significa che alcune istruzioni potrebbero essere eseguite con LAQ, mentre altre potrebbero essere eseguite senza LAQ. Ad esempio, LAQ potrebbe essere disabilitato per un piano di query, ma abilitato per il database e viceversa.
Limitazioni di LAQ
Il blocco dopo la qualifica non viene usato negli scenari seguenti:
- Quando disabilitato dall'euristica LAQ.
- Quando si usano suggerimenti di blocco in conflitto, ad esempio
UPDLOCK,READCOMMITTEDLOCK,XLOCK, oHOLDLOCK. - Quando il livello di isolamento della transazione è diverso da
READ COMMITTEDo quando l'opzione diREAD_COMMITTED_SNAPSHOTdatabase è disabilitata. - Quando si modifica una tabella con un indice columnstore.
- Quando l'istruzione DML include l'assegnazione di variabili.
- Quando l'istruzione DML contiene la clausola
OUTPUT. - Quando l'istruzione DML usa più di un operatore index seek o scan per leggere le righe da modificare.
- Nelle
MERGEistruzioni.
Modifiche al comportamento delle query con blocchi ottimizzati e RCSI
I carichi di lavoro simultanei con isolamento dello snapshot read committed (RCSI) basati su un ordine di esecuzione rigoroso delle transazioni potrebbero riscontrare un comportamento di query diverso quando è abilitato il blocco ottimizzato.
Si consideri l'esempio seguente in cui la transazione T2 aggiorna la tabella t4 in base alla colonna b aggiornata durante la transazione T1.
CREATE TABLE t4
(
a int NOT NULL,
b int NULL
);
INSERT INTO t4
VALUES (1,1);
GO
| Sessione 1 | Sessione 2 |
|---|---|
BEGIN TRANSACTION T1;UPDATE t4SET b = 2WHERE a = 1; |
|
BEGIN TRANSACTION T2;UPDATE t4SET b = 3WHERE b = 2; |
|
COMMIT TRANSACTION; |
|
COMMIT TRANSACTION; |
Si valuterà ora il risultato dello scenario precedente con e senza blocco dopo la qualificazione (LAQ).
Senza LAQ
Senza LAQ, l’UPDATEistruzione nella transazione T2 verrà bloccata e attenderà il completamento della transazione T1. Al termine di T1, T2 aggiorna la colonna b delle impostazioni di riga in 3 perché il predicato è soddisfatto.
Dopo aver eseguito il commit di entrambe le transazioni, la tabella t4 contiene le righe seguenti:
a | b
1 | 3
Con LAQ
Con LAQ, la transazione T2 usa la versione di commit più recente della riga in cui la colonna b è uguale a per 1 valutarne il predicato (b = 2). La riga non soddisfa i requisiti. Pertanto, viene ignorata e l'istruzione viene completata senza essere stata bloccata dalla transazione T1. In questo esempio LAQ rimuove il blocco ma genera risultati diversi.
Dopo aver eseguito il commit di entrambe le transazioni, la tabella t4 contiene le righe seguenti:
a | b
1 | 2
Important
Anche senza LAQ, le applicazioni non devono presupporre che il motore di database garantisca un ordinamento rigoroso senza usare hint di blocco quando vengono usati i livelli di isolamento basati sul controllo delle versioni delle righe. La raccomandazione generale per i clienti con carichi di lavoro simultanei in RCSI che si basano su un ordine di esecuzione rigoroso delle transazioni (come illustrato nell’esempio precedente) consiste nell'usare livelli di isolamento più rigorosi come REPEATABLE READ e SERIALIZABLE.
Aggiunte di diagnostica per il blocco ottimizzato
I miglioramenti seguenti consentono di monitorare e risolvere i problemi di blocco e deadlock quando è abilitato il blocco ottimizzato:
- Tipi di attesa per il blocco ottimizzato
-
XACTtipi di attesa per ilSblocco sul TID e descrizioni delle risorse in sys.dm_os_wait_stats:-
LCK_M_S_XACT_READ- Si verifica quando un'attività è in attesa di un blocco condiviso su un tipoXACTwait_resource, con la finalità di leggere. -
LCK_M_S_XACT_MODIFY- Si verifica quando un'attività è in attesa di un blocco condiviso su un tipoXACTwait_resource, con la finalità di modificare. -
LCK_M_S_XACT: si verifica quando un'attività è in attesa di un blocco condiviso del tipoXACTwait_resource, dove non è possibile dedurre l'intento. Questo scenario non è comune.
-
-
- Blocco della visibilità delle risorse
- Risorse bloccate
XACT. Per altre informazioni, vedereresource_descriptionin sys.dm_tran_locks.
- Risorse bloccate
- Attendere la visibilità delle risorse
- Risorse in attesa
XACT. Per altre informazioni, vederewait_resourcein sys.dm_exec_requests.
- Risorse in attesa
- Grafico del deadlock
- In ogni risorsa del report deadlock
<resource-list>, ogni<xactlock>elemento segnala le risorse sottostanti e informazioni specifiche per i blocchi di ogni membro di un deadlock. Per altre informazioni e un esempio, vedere Blocchi ottimizzati e deadlock.
- In ogni risorsa del report deadlock
- Eventi estesi
- L'evento
lock_after_qual_stmt_abortviene generato quando un'istruzione viene rielaborata internamente a causa di un conflitto con un'altra transazione. Per altre informazioni, vedere la sezione relativa al blocco dopo qualificazione (LAQ). - L'evento
locking_statsviene generato per ogni database ogni pochi minuti e fornisce statistiche di blocco aggregate per l'intervallo di tempo, come il numero di escalation dei blocchi, se il blocco TID e i componenti LAQ di blocco ottimizzati sono abilitati, e il numero di query in cui LAQ non è stato utilizzato per vari motivi. Questo evento viene attivato anche quando il blocco ottimizzato è disabilitato. - In SQL Server e Azure SQL Managed Instance, l'evento
locking_stats2viene generato per ogni database ogni pochi minuti e fornisce le statistiche sui blocchi di indice ignorati e le euristiche LAQ per l'intervallo di tempo.
- L'evento
Procedure consigliate con il blocco ottimizzato
Abilitare isolamento dello snapshot commit di lettura (RCSI)
Per ottimizzare i vantaggi del blocco ottimizzato, è consigliabile abilitare l'isolamento dello snapshot read committed (RCSI) nel database e usare READ COMMITTED l'isolamento come livello di isolamento predefinito.
Nel database SQL di Azure e nel database SQL di Microsoft Fabric, RCSI è abilitato per impostazione predefinita ed READ COMMITTED è il livello di isolamento predefinito. Con RCSI abilitato e quando si usa READ COMMITTED il livello di isolamento, i lettori leggono una versione della riga dallo snapshot acquisito all'inizio dell'istruzione. Con LAQ, i writer qualificano le righe per ogni predicato in base alla versione di cui è stato eseguito il commit più recente della riga senza acquisire U blocchi. Con LAQ, una query attende solo se la riga è idonea ed è presente una transazione di scrittura attiva in tale riga. L'idoneità in base alla versione di cui è stato eseguito il commit più recente e al blocco delle sole righe qualificate riduce il blocco e aumenta la concorrenza.
Evitare di bloccare hint
Anche se gli hint di tabella e query, ad esempio UPDLOCK, READCOMMITTEDLOCK, XLOCK, HOLDLOCKe così via, vengono rispettati quando è abilitato il blocco ottimizzato, riducono il vantaggio del blocco ottimizzato. Gli hint di blocco costringono il motore di database ad accettare blocchi di riga o di pagina e mantenerli fino alla fine della transazione, per rispettare la finalità degli hint di blocco. La logica di alcune applicazioni prevede dove sono necessari hint di blocco, ad esempio durante la lettura di una riga con UPDLOCKhint, per aggiornarlo in un secondo momento. È consigliabile usare hint di blocco solo dove richiesto.
Con il blocco ottimizzato, non ci sono restrizioni sulle query esistenti e non è necessario riscriverle. Le query che non usano hint traggono il massimo vantaggio dai blocchi ottimizzati.
Un suggerimento di tabella in una tabella in una query non disabilita il blocco ottimizzato per altre tabelle nella stessa query. Inoltre, il blocco ottimizzato influisce solo sul comportamento di blocco delle tabelle aggiornate da un'istruzione DML come INSERT, UPDATE, DELETE, o MERGE.. Per esempio:
CREATE TABLE t5
(
a int NOT NULL,
b int NOT NULL
);
CREATE TABLE t6
(
a int NOT NULL,
b int NOT NULL
);
GO
INSERT INTO t5 VALUES (1,10),(2,20),(3,30);
INSERT INTO t6 VALUES (1,10),(2,20),(3,30);
GO
UPDATE t5 SET t5.b = t6.b
FROM t5
INNER JOIN t6 WITH (UPDLOCK)
ON t5.a = t6.a;
Nell'esempio di query precedente, l’hint di blocco interesserà solo la tabella t6, mentre t5 può comunque trarre vantaggio dal blocco ottimizzato.
UPDATE t5
SET t5.b = t6.b
FROM t5 WITH (REPEATABLEREAD)
INNER JOIN t6
ON t5.a = t6.a;
Nell'esempio di query precedente, solo la tabella t5 userà il livello di isolamento REPEATABLE READ e manterrà i blocchi fino alla fine della transazione. Altri aggiornamenti per t5 possono comunque trarre vantaggio dal blocco ottimizzato. Lo stesso vale per l'hint HOLDLOCK.
Domande frequenti
Il blocco ottimizzato è attivato per impostazione predefinita nei database nuovi ed esistenti?
Nel database SQL di Azure, nell'istanza gestita di Azure SQLAUTD e sì nel database SQL in Microsoft Fabric. In SQL Server 2025 (17.x) il blocco ottimizzato è disabilitato per impostazione predefinita, ma può essere abilitato in qualsiasi database utente con ripristino accelerato del database abilitato.
Come è possibile rilevare se è abilitato il blocco ottimizzato?
Vedere La funzionalità di blocco ottimizzato è abilitata?
Cosa accade se si desidera forzare il blocco delle query nonostante il blocco ottimizzato?
Se RCSI è abilitato, utilizzare l'hint di tabella READCOMMITTEDLOCK per forzare il blocco tra due query quando il locking ottimizzato è abilitato.
Il blocco ottimizzato viene usato nelle repliche secondarie di sola lettura?
No, perché le istruzioni DML non possono essere eseguite su repliche di sola lettura e i blocchi di riga e di pagina corrispondenti non vengono acquisiti.
Il blocco ottimizzato viene usato quando si modificano i dati in tempdb e nelle tabelle temporanee?
Non al momento.