Saya berjuang melawan NOLOCK di lingkungan saya saat ini. Salah satu argumen yang saya dengar adalah bahwa overhead penguncian memperlambat kueri. Jadi, saya membuat tes untuk melihat seberapa besar biaya overhead ini.
Saya menemukan bahwa NOLOCK sebenarnya memperlambat pemindaian saya.
Awalnya saya senang, tapi sekarang saya bingung. Apakah pengujian saya salah? Bukankah seharusnya NOLOCK memungkinkan pemindaian yang sedikit lebih cepat? Apa yang sedang terjadi disini?
Ini skrip saya:
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())
Apa yang saya coba tidak berhasil:
- Berjalan di server yang berbeda (hasil yang sama, server 2016-SP1 dan 2016-SP2, keduanya sunyi)
- Berjalan di dbfiddle.uk pada versi yang berbeda (hasil berisik, tetapi mungkin sama)
- SET TINGKAT ISOLASI alih-alih petunjuk (hasil yang sama)
- Mematikan eskalasi kunci di atas meja (hasil yang sama)
- Memeriksa waktu pelaksanaan aktual pemindaian dalam rencana kueri aktual (hasil yang sama)
- Kompilasi ulang petunjuk (hasil yang sama)
- Baca hanya filegroup (hasil yang sama)
Eksplorasi yang paling menjanjikan datang dari menghapus variabel sampah dan menggunakan kueri tanpa hasil. Awalnya ini menunjukkan NOLOCK sedikit lebih cepat, tetapi ketika saya menunjukkan demo kepada bos saya, NOLOCK kembali menjadi lebih lambat.
Ada apa dengan NOLOCK yang memperlambat pemindaian dengan penugasan variabel?