ปรับขนาดคอลัมน์แต่ละคอลัมน์ให้เหมาะสม อย่าใช้ขนาด "มาตรฐาน" สำหรับแต่ละคอลัมน์ หากคุณต้องการเพียง 30 ตัวอักษรทำไมต้องสร้างคอลัมน์ที่สามารถรองรับ 255 ได้ ฉันดีใจที่คุณไม่สนับสนุนให้ใช้varchar(max)
คอลัมน์สตริงของคุณ
นี่เป็นคำแนะนำที่รอบคอบโดยเฉพาะหากคุณต้องการจัดทำดัชนีคอลัมน์หรือหากคุณใช้คอลัมน์เป็นคีย์หลักและมีการอ้างอิงคีย์ต่างประเทศ SQL Server ใช้ขนาดของแต่ละคอลัมน์ในเครื่องมือเพิ่มประสิทธิภาพแบบสอบถามเพื่อทำความเข้าใจข้อกำหนดหน่วยความจำโดยประมาณสำหรับการประมวลผลแบบสอบถาม การมีคอลัมน์ขนาดใหญ่อาจส่งผลเสียต่อประสิทธิภาพการทำงาน
ดัชนีในคอลัมน์ที่มีขนาดใหญ่เกินไปอาจทำให้เกิดข้อผิดพลาดในการสร้าง:
CREATE TABLE dbo.WideIndex
(
col1 varchar(255) NOT NULL
, col2 varchar(255) NOT NULL
, col3 varchar(600) NOT NULL
);
CREATE INDEX IX_WideIndex_01
ON dbo.WideIndex (col1, col2, col3);
ความพยายามในการสร้างดัชนีเหนือผลลัพธ์ในคำเตือนนี้:
คำเตือน! ความยาวสูงสุดของคีย์คือ 900 ไบต์ ดัชนี 'IX_WideIndex_01' มีความยาวสูงสุด 1110 ไบต์ สำหรับการรวมกันของค่าขนาดใหญ่การดำเนินการแทรก / อัปเดตจะล้มเหลว
900 ไบต์เป็นขนาดคีย์สูงสุดสำหรับดัชนีคลัสเตอร์ (และดัชนีที่ไม่ใช่คลัสเตอร์ใน SQL Server 2012 และรุ่นเก่ากว่า) 1700 ไบต์เป็นขนาดคีย์สูงสุดสำหรับดัชนีที่ไม่ได้ทำคลัสเตอร์บน SQL Server เวอร์ชันที่ใหม่กว่า หากคุณออกแบบคอลัมน์ที่มีความกว้างทั่วไปเช่น (255) คุณอาจพบคำเตือนนี้บ่อยกว่าที่คาดไว้
ในกรณีที่คุณมีความสนใจในการจัดเก็บข้อมูลภายในคุณสามารถใช้การทดสอบเล็ก ๆ ต่อไปนี้เพื่อทำความเข้าใจวิธีที่ SQL Server จัดเก็บข้อมูลแถวร้านที่ไม่มีการบีบอัด
ก่อนอื่นเราจะสร้างตารางที่เราสามารถเก็บคอลัมน์ที่มีขนาดต่าง ๆ ได้:
IF OBJECT_ID(N'dbo.varchartest', N'U') IS NOT NULL
DROP TABLE dbo.varchartest;
GO
CREATE TABLE dbo.varchartest
(
varchar30 varchar(30) NOT NULL
, varchar255 varchar(255) NOT NULL
, varchar256 varchar(256) NOT NULL
);
ตอนนี้เราจะแทรกแถวเดียว:
INSERT INTO dbo.varchartest (varchar30, varchar255, varchar256)
VALUES (REPLICATE('1', 30), REPLICATE('2', 255), REPLICATE('3', 256));
แบบสอบถามนี้ใช้ฟังก์ชันที่ไม่มีเอกสารและไม่สนับสนุนsys.fn_RowDumpCracker
และsys.fn_PhyslocCracker
แสดงรายละเอียดที่น่าสนใจเกี่ยวกับตาราง:
SELECT rdc.*
, plc.*
FROM dbo.varchartest vct
CROSS APPLY sys.fn_RowDumpCracker(%%rowdump%%) rdc
CROSS APPLY sys.fn_physlocCracker(%%physloc%%) plc
ผลลัพธ์จะคล้ายกับสิ่งนี้:
╔═════════════════════╦════════════╦═════════╦════ ══════╦══════════════════════════╦══════════╦═════ ════════╦═════════════╦═════════╦═════════╦═══════ ══╗
║ partition_id ║ colName ║ IsInrow ║ IsSparse ║ IsRecordPrefix การบีบอัด║ IsSymbol ║คำนำหน้าไบต์
╠═════════════════════╬════════════╬═════════╬════ ══════╬══════════════════════════╬══════════╬═════ ════════╬═════════════╬═════════╬═════════╬═══════ ══╣
║ 1729382263096344576 ║ varchar30 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 30 ║ 1 ║ 1912 ║ 0 ║
║ 1729382263096344576 ║ varchar255 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 255 ║ 1 ║ 1912 ║ 0 ║
║ 1729382263096344576 ║ varchar256 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 0 ║ 256 ║ 1 ║ 1912 ║ 0 ║
╚═════════════════════╩════════════╩═════════╩════ ══════╩══════════════════════════╩══════════╩═════ ════════╩═════════════╩═════════╩═════════╩═══════ ══╝
อย่างที่คุณเห็นค่าInRowLength
สำหรับแต่ละค่าจะปรากฏพร้อมกับตำแหน่งที่เก็บข้อมูลฟิสิคัลของแต่ละแถว - "file_id", "page_id" และ "slot_id"
หากเรานำค่าfile_id
และpage_id
จากผลลัพธ์แบบสอบถามด้านบนและเรียกใช้DBCC PAGE
ด้วยเราสามารถเห็นเนื้อหาของหน้าจริงได้:
DBCC TRACEON (3604); --send display to the client
DBCC PAGE (tempdb, 1, 1912, 3); --database, file_id, page_id, 3 to show page contents
DBCC TRACEOFF (3604);--reset display back to the error log
ผลลัพธ์จากเครื่องของฉันคือ:
หน้า: (1: 1912)
กันชน:
BUF @ 0x00000000FF5B2E80
bpage = 0x0000000024130000 bhash = 0x00000000000000000000 bpageno = (1: 1912)
bdbid = 2 Breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 32497 bstat = 0x10b
บล็อก = 0x212121cc bnext = 0x00000000000000000000
ส่วนหัวของหน้า:
หน้า @ 0x0000000024130000
m_pageId = (1: 1912) m_headerVersion = 1 m_type = 1
m_typeFlagBits = 0x0 m_level = 0 m_flagBits = 0x8000
m_objId (AllocUnitId.idObj) = 98834 m_indexId (AllocUnitId.idInd) = 7936
ข้อมูลเมตา: AllocUnitId = 2233785421652951040
ข้อมูลเมตา: PartitionId = 1945555045333008384 ข้อมูลเมตา: IndexId = 0
ข้อมูลเมตา: ObjectId = 34099162 m_prevPage = (0: 0) m_nextPage = (0: 0)
pminlen = 4 m_slotCnt = 1 m_freeCnt = 7538
m_freeData = 652 m_reservedCnt = 0 m_lsn = (35: 210971: 362)
m_xactReserved = 0 m_xdesId = (0: 0) m_ghostRecCnt = 0
m_tornBits = 0 DB Frag ID = 1
สถานะการจัดสรร
GAM (1: 2) = จัดสรร SGAM (1: 3) = ไม่จัดสรร PFS (1: 1) = 0x41 จัดสรร 50_PCT_FULL
DIFF (1: 6) = ไม่เปลี่ยนแปลง ML (1: 7) = ไม่ MIN_LOGGED
ช่อง 0 ออฟเซ็ต 0x60 ความยาว 556
ประเภทระเบียน = Primary_RECORD คุณสมบัติบันทึก = NULL_BITMAP VARIABLE_COLUMNS
ขนาดบันทึก = 556
Memory Dump @ 0x000000005145A060
00000000000000000000: 30000400 03000003 002d002c 012c0231 31313131 0 ........-.,.,. 11111
0000000000000014: 31313131 31313131 31313131 31313131 31313131 111111111111111111111111
0000000000000028: 31313131 31323232 32323232 32323232 32323232 1111122222222222222222
000000000000003C: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
0000000000000050: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
0000000000000064: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
0000000000000078: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
000000000000008C: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
000000000000000000A0: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
00000000000000BB4: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
00000000000000CC8: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
00000000000000DCDC: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
00000000000000FF0: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
0000000000000104: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
0000000000000118: 32323232 32323232 32323232 32323232 32323232 222222222222222222222222
000000000000012C: 33333333 33333333 33333333 33333333 33333333 33333333333333333333
0000000000000140: 33333333 33333333 33333333 33333333 33333333 333333333333333333
0000000000000154: 33333333 33333333 33333333 33333333 33333333 33333333333333333333
0000000000000168: 33333333 33333333 33333333 33333333 33333333 33333333333333333333
000000000000017C: 33333333 33333333 33333333 33333333 33333333 33333333333333333333
0000000000000190: 33333333 33333333 33333333 33333333 33333333 333333333333333333
00000000000001A4: 33333333 33333333 33333333 33333333 33333333 333333333333333333
00000000000001B8: 33333333 33333333 33333333 33333333 33333333 333333333333333333
00000000000001CC: 33333333 33333333 33333333 33333333 33333333 333333333333333333
00000000000001E0: 33333333 33333333 33333333 33333333 33333333 333333333333333333
00000000000001F4: 33333333 33333333 33333333 33333333 33333333 333333333333333333
0000000000000208: 33333333 33333333 33333333 33333333 33333333 33333333333333333333
000000000000021C: 33333333 33333333 33333333 33333333 33333333333333
ช่อง 0 คอลัมน์ 1 ชดเชย 0xf ความยาว 30 ความยาว (ทางกายภาพ) 30
varchar30 = 11111111111111111111111111111111
ช่อง 0 คอลัมน์ 2 ออฟเซ็ต 0x2d ความยาว 255 ความยาว (ทางกายภาพ) 255
varchar255 = 22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222
ช่อง 0 คอลัมน์ 3 Offset 0x12c ความยาว 256 ความยาว (ทางกายภาพ) 256
varchar256 = 333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
3333333333333333333333333333333333333333333