此时此刻是否重要?
我在互联网上看到了一些帖子,但它们适用于Oracle和MySQL.
我们有Microsoft sql Server 2016企业版,它如何应用于这种环境?
现在说,例如,如果我告诉我的客户保持例如,文本描述为255个字符而不是256个,那有什么区别?我读到的内容“最大长度为255个字符,DBMS可以选择使用单个字节来指示字段中的数据长度.如果限制为256或更大,则需要两个字节.”这是真的?
解决方法
如果您需要索引列,或者您使用列作为主键并且它具有外键引用,那么这是特别谨慎的建议. 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);
上面创建索引的尝试导致此警告:
Warning! The maximum key length is 900 bytes. The index ‘IX_WideIndex_01’ has maximum length of 1110 bytes. For some combination of large values,the insert/update operation will fail.
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 ║ IsRecordPrefixCompressed ║ IsSymbol ║ PrefixBytes ║ InRowLength ║ file_id ║ page_id ║ slot_id ║ ╠═════════════════════╬════════════╬═════════╬══════════╬══════════════════════════╬══════════╬═════════════╬═════════════╬═════════╬═════════╬═════════╣ ║ 1729382263096344576 ║ varchar30 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 30 ║ 1 ║ 1912 ║ 0 ║ ║ 1729382263096344576 ║ varchar255 ║ 1 ║ 0 ║ 0 ║ 0 ║ 0 ║ 255 ║ 1 ║ 1912 ║ 0 ║ ║ 1729382263096344576 ║ varchar256 ║ 1 ║ 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
我的机器的结果是:
PAGE: (1:1912) BUFFER: BUF @0x00000000FF5B2E80 bpage = 0x0000000024130000 bhash = 0x0000000000000000 bpageno = (1:1912) bdbid = 2 breferences = 0 bcputicks = 0 bsampleCount = 0 bUse1 = 32497 bstat = 0x10b blog = 0x212121cc bnext = 0x0000000000000000 PAGE HEADER: Page @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 Metadata: AllocUnitId = 2233785421652951040 Metadata: PartitionId = 1945555045333008384 Metadata: IndexId = 0 Metadata: 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 Allocation Status GAM (1:2) = ALLOCATED SGAM (1:3) = NOT ALLOCATED PFS (1:1) = 0x41 ALLOCATED 50_PCT_FULL DIFF (1:6) = NOT CHANGED ML (1:7) = NOT MIN_LOGGED Slot 0 Offset 0x60 Length 556 Record Type = PRIMARY_RECORD Record Attributes = NULL_BITMAP VARIABLE_COLUMNS Record Size = 556 Memory Dump @0x000000005145A060 0000000000000000: 30000400 03000003 002d002c 012c0231 31313131 0........-.,.,.11111 0000000000000014: 31313131 31313131 31313131 31313131 31313131 11111111111111111111 0000000000000028: 31313131 31323232 32323232 32323232 32323232 11111222222222222222 000000000000003C: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 0000000000000050: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 0000000000000064: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 0000000000000078: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 000000000000008C: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 00000000000000A0: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 00000000000000B4: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 00000000000000C8: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 00000000000000DC: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 00000000000000F0: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 0000000000000104: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 0000000000000118: 32323232 32323232 32323232 32323232 32323232 22222222222222222222 000000000000012C: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 0000000000000140: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 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 33333333333333333333 00000000000001A4: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 00000000000001B8: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 00000000000001CC: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 00000000000001E0: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 00000000000001F4: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 0000000000000208: 33333333 33333333 33333333 33333333 33333333 33333333333333333333 000000000000021C: 33333333 33333333 33333333 33333333 3333333333333333 Slot 0 Column 1 Offset 0xf Length 30 Length (physical) 30 varchar30 = 111111111111111111111111111111 Slot 0 Column 2 Offset 0x2d Length 255 Length (physical) 255 varchar255 = 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222 222222222222222222222222222222222222222222 Slot 0 Column 3 Offset 0x12c Length 256 Length (physical) 256 varchar256 = 3333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333 3333333333333333333333333333333333333333333