Ich kämpfe in meiner aktuellen Umgebung gegen NOLOCK. Ein Argument, das ich gehört habe, ist, dass der Aufwand für das Sperren eine Abfrage verlangsamt. Also habe ich einen Test entwickelt, um zu sehen, wie hoch dieser Overhead sein könnte.
Ich habe festgestellt, dass NOLOCK meinen Scan tatsächlich verlangsamt.
Anfangs war ich begeistert, aber jetzt bin ich nur noch verwirrt. Ist mein Test irgendwie ungültig? Sollte NOLOCK nicht tatsächlich einen etwas schnelleren Scan zulassen? Was passiert hier?
Hier ist mein Skript:
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())
Was ich versucht habe, hat nicht funktioniert:
- Läuft auf verschiedenen Servern (gleiche Ergebnisse, Server waren 2016-SP1 und 2016-SP2, beide leise)
- Laufen auf dbfiddle.uk auf verschiedenen Versionen (laut, aber wahrscheinlich die gleichen Ergebnisse)
- SET ISOLATION LEVEL anstelle von Hinweisen (gleiche Ergebnisse)
- Deaktivieren der Sperreneskalation auf dem Tisch (gleiche Ergebnisse)
- Untersuchen der tatsächlichen Ausführungszeit des Scans im tatsächlichen Abfrageplan (gleiche Ergebnisse)
- Hinweis neu kompilieren (gleiche Ergebnisse)
- Schreibgeschützte Dateigruppe (gleiche Ergebnisse)
Die vielversprechendste Untersuchung ergibt sich aus dem Entfernen der Papierkorbvariablen und der Verwendung einer Abfrage ohne Ergebnisse. Anfangs zeigte dies, dass NOLOCK etwas schneller war, aber als ich meinem Chef die Demo zeigte, war NOLOCK wieder langsamer.
Was ist mit NOLOCK, das einen Scan mit variabler Zuweisung verlangsamt?

