ค่าที่เกิน 8000 ไบต์ไม่สามารถจัดเก็บ "แบบอินไลน์" พวกเขาจะถูกเก็บไว้ในหน้า LOB คุณสามารถดูนี้กับsys.dm_db_index_physical_stats เริ่มด้วยตารางง่ายๆ
USE tempdb;
DROP TABLE IF EXISTS #LOB_FOR_ME;
CREATE TABLE #LOB_FOR_ME (
ID BIGINT,
MAX_VERNON_WAS_HERE VARCHAR(MAX)
);
CREATE INDEX IX ON #LOB_FOR_ME (ID) INCLUDE (MAX_VERNON_WAS_HERE);
ตอนนี้แทรกบางแถวด้วยค่าที่ใช้ 8000 ไบต์สำหรับVARCHAR(MAX)
คอลัมน์และตรวจสอบ DMF:
USE tempdb;
INSERT INTO #LOB_FOR_ME
SELECT 1, REPLICATE('Z', 8000)
FROM master..spt_values;
SELECT index_level, index_type_desc, alloc_unit_type_desc, page_count, record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('#LOB_FOR_ME'), 2, NULL , 'DETAILED');
ไม่มีหน้า LOB ในดัชนี:
╔═════════════╦════════════════════╦══════════════════════╦════════════╦══════════════╗
║ index_level ║ index_type_desc ║ alloc_unit_type_desc ║ page_count ║ record_count ║
╠═════════════╬════════════════════╬══════════════════════╬════════════╬══════════════╣
║ 0 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 2540 ║ 2540 ║
║ 1 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 18 ║ 2540 ║
║ 2 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 1 ║ 18 ║
╚═════════════╩════════════════════╩══════════════════════╩════════════╩══════════════╝
แต่ถ้าฉันเพิ่มแถวที่มีค่าที่รับ 8001 ไบต์:
USE tempdb;
INSERT INTO #LOB_FOR_ME
SELECT 2, REPLICATE(CAST('Z' AS VARCHAR(MAX)), 8001)
FROM master..spt_values;
SELECT index_level, index_type_desc, alloc_unit_type_desc, page_count, record_count
FROM sys.dm_db_index_physical_stats(DB_ID(), OBJECT_ID('#LOB_FOR_ME'), 2, NULL , 'DETAILED');
ตอนนี้ฉันมี 1 LOB หน้าในดัชนีสำหรับทุกแถวที่ฉันเพิ่งแทรก:
╔═════════════╦════════════════════╦══════════════════════╦════════════╦══════════════╗
║ index_level ║ index_type_desc ║ alloc_unit_type_desc ║ page_count ║ record_count ║
╠═════════════╬════════════════════╬══════════════════════╬════════════╬══════════════╣
║ 0 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 2556 ║ 5080 ║
║ 1 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 18 ║ 2556 ║
║ 2 ║ NONCLUSTERED INDEX ║ IN_ROW_DATA ║ 1 ║ 18 ║
║ 0 ║ NONCLUSTERED INDEX ║ LOB_DATA ║ 2540 ║ 2540 ║
╚═════════════╩════════════════════╩══════════════════════╩════════════╩══════════════╝
นอกจากนี้คุณยังสามารถดูได้ด้วยSET STATISTICS IO ON;
และแบบสอบถามที่ถูกต้อง พิจารณาแบบสอบถามต่อไปนี้ที่ดูเฉพาะแถวที่มี 8000 ไบต์เท่านั้น:
SELECT SUM(LEN(MAX_VERNON_WAS_HERE))
FROM #LOB_FOR_ME
WHERE ID = 1;
ผลลัพธ์เมื่อดำเนินการ:
จำนวนการสแกน 1, การอ่านเชิงตรรกะ 2560, การอ่านทางกายภาพ 0, การอ่านล่วงหน้าอ่าน 0, lob ตรรกะอ่าน 0, lob การอ่านทางกายภาพ 0, lob การอ่านล่วงหน้าอ่าน 0
ถ้าฉันค้นหาแถวด้วย 8001 ไบต์แทน:
SELECT SUM(LEN(MAX_VERNON_WAS_HERE))
FROM #LOB_FOR_ME
WHERE ID = 2;
ตอนนี้ฉันเห็นลูกเทนนิสอ่าน:
จำนวนการสแกน 1, การอ่านเชิงตรรกะ 20, การอ่านทางกายภาพ 0, การอ่านล่วงหน้าอ่าน 0, lob ตรรกะอ่าน 5080, lob การอ่านทางกายภาพ 0, lob การอ่านล่วงหน้าอ่าน 0