ฉันต่อสู้กับ NOLOCK ในสภาพแวดล้อมปัจจุบันของฉัน อาร์กิวเมนต์หนึ่งที่ฉันได้ยินคือโอเวอร์เฮดของการล็อกทำให้การสืบค้นช้าลง ดังนั้นฉันจึงวางแผนการทดสอบเพื่อดูว่าค่าใช้จ่ายนี้จะมากแค่ไหน
ฉันค้นพบว่า NOLOCK จริง ๆ แล้วการสแกนของฉันช้าลง
ตอนแรกฉันดีใจ แต่ตอนนี้ฉันสับสน การทดสอบของฉันไม่ถูกต้องอย่างใด? NOLOCK ไม่ควรอนุญาตให้สแกนเร็วขึ้นเล็กน้อยจริง ๆ หรือ เกิดอะไรขึ้นที่นี่
นี่คือสคริปต์ของฉัน:
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())
สิ่งที่ฉันพยายามที่ไม่ทำงาน:
- ทำงานบนเซิร์ฟเวอร์ที่แตกต่างกัน (ผลลัพธ์เดียวกันเซิร์ฟเวอร์คือ 2016-SP1 และ 2016-SP2 ทั้งสองเงียบ)
- ทำงานบน dbfiddle.ukในรุ่นต่าง ๆ (มีเสียงดัง แต่อาจเป็นผลลัพธ์เดียวกัน)
- SET ISOLATION LEVEL แทนคำใบ้ (ผลลัพธ์เดียวกัน)
- การปิดการเพิ่มล็อคบนโต๊ะ (ผลลัพธ์เดียวกัน)
- การตรวจสอบเวลาดำเนินการจริงของการสแกนในแผนแบบสอบถามจริง (ผลลัพธ์เดียวกัน)
- คำแนะนำการคอมไพล์ใหม่ (ผลลัพธ์เดียวกัน)
- อ่านเฉพาะกลุ่มไฟล์ (ผลลัพธ์เดียวกัน)
การสำรวจที่มีแนวโน้มมากที่สุดนั้นมาจากการลบตัวแปรถังขยะและใช้แบบสอบถามที่ไม่มีผลลัพธ์ ในขั้นต้นนี่แสดงให้เห็นว่า NOLOCK เร็วขึ้นเล็กน้อย แต่เมื่อฉันแสดงตัวอย่างให้เจ้านายของฉัน NOLOCK กลับมาช้าลง
อะไรเกี่ยวกับ NOLOCK ที่ทำให้การสแกนช้าลงด้วยการกำหนดตัวแปร?