适当调整每一列的大小。不要为每列使用“标准”大小。如果只需要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个字节。对于大值的某些组合,插入/更新操作将失败。
群集索引(以及SQL Server 2012和更早版本上的非群集索引)的最大键大小为900个字节。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)
缓冲:
BUF @ 0x00000000FF5B2E80
bpage = 0x0000000024130000 bhash = 0x0000000000000000 bpageno =(1:1912)
bdbid = 2 breferences = 0 bcputicks = 0
bsampleCount = 0 bUse1 = 32497 bstat = 0x10b
博客= 0x212121cc bnext = 0x0000000000000000
页面标题:
页面@ 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)= NOT CHANGED ML(1:7)= NOT MIN_LOGGED
插槽0偏移0x60长度556
记录类型= PRIMARY_RECORD记录属性= NULL_BITMAP VARIABLE_COLUMNS
记录大小= 556
内存转储@ 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
插槽0列1偏移量0xf长度30长度(物理)30
varchar30 = 111111111111111111111111111111
插槽0列2偏移量0x2d长度255长度(物理)255
varchar255 = 2222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
22222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222222
222222222222222222222222222222222222222222222
插槽0列3偏移量0x12c长度256长度(物理)256
varchar256 = 33333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333333
3333333333333333333333333333333333333333333333