Sto combattendo contro NOLOCK nel mio ambiente attuale. Un argomento che ho sentito è che l'overhead del blocco rallenta una query. Quindi, ho ideato un test per vedere quanto potrebbe essere questo sovraccarico.
Ho scoperto che NOLOCK in realtà rallenta la mia scansione.
All'inizio ero felice, ma ora sono solo confuso. Il mio test non è valido in qualche modo? NOLOCK non dovrebbe effettivamente consentire una scansione leggermente più veloce? Cosa sta succedendo qui?
Ecco la mia sceneggiatura:
USE TestDB
GO
--Create a five-million row table
DROP TABLE IF EXISTS dbo.JustAnotherTable
GO
CREATE TABLE dbo.JustAnotherTable (
ID INT IDENTITY PRIMARY KEY,
notID CHAR(5) NOT NULL )
INSERT dbo.JustAnotherTable
SELECT TOP 5000000 'datas'
FROM sys.all_objects a1
CROSS JOIN sys.all_objects a2
CROSS JOIN sys.all_objects a3
/********************************************/
-----Testing. Run each multiple times--------
/********************************************/
--How fast is a plain select? (I get about 587ms)
DECLARE @trash CHAR(5), @dt DATETIME = SYSDATETIME()
SELECT @trash = notID --trash variable prevents any slowdown from returning data to SSMS
FROM dbo.JustAnotherTable
ORDER BY ID
OPTION (MAXDOP 1)
SELECT DATEDIFF(MILLISECOND,@dt,SYSDATETIME())
----------------------------------------------
--Now how fast is it with NOLOCK? About 640ms for me
DECLARE @trash CHAR(5), @dt DATETIME = SYSDATETIME()
SELECT @trash = notID
FROM dbo.JustAnotherTable (NOLOCK)
ORDER BY ID --would be an allocation order scan without this, breaking the comparison
OPTION (MAXDOP 1)
SELECT DATEDIFF(MILLISECOND,@dt,SYSDATETIME())
Quello che ho provato che non ha funzionato:
- In esecuzione su server diversi (stessi risultati, i server erano 2016-SP1 e 2016-SP2, entrambi silenziosi)
- In esecuzione su dbfiddle.uk su versioni diverse (risultati rumorosi, ma probabilmente gli stessi)
- IMPOSTA LIVELLO ISOLAMENTO anziché suggerimenti (stessi risultati)
- Disattivazione dell'escalation dei blocchi sul tavolo (stessi risultati)
- Esame del tempo di esecuzione effettivo della scansione nel piano di query effettivo (stessi risultati)
- Ricompila suggerimento (stessi risultati)
- Filegroup di sola lettura (stessi risultati)
L'esplorazione più promettente viene dalla rimozione della variabile cestino e dall'utilizzo di una query senza risultati. Inizialmente questo ha mostrato NOLOCK leggermente più veloce, ma quando ho mostrato la demo al mio capo, NOLOCK è tornato ad essere più lento.
Cos'è NOLOCK che rallenta una scansione con assegnazione variabile?

