一个可以有所作为的示例是,它可以防止性能优化,该性能优化避免使用后触发将行版本控制信息添加到表中。
这在此处由SQL Kiwi涵盖
所存储数据的实际大小无关紧要-潜在的大小至关重要。
同样,如果自2016年以来使用内存优化表,则有可能使用LOB列或列宽度的组合,这些组合可能会超出行数限制,但要付出代价。
(Max)列始终存储在行外。对于其他列,如果表定义中的数据行大小可以超过8,060字节,则SQL Server会将最大的可变长度列下推。同样,它不取决于您存储在此处的数据量。
这会对内存消耗和性能产生很大的负面影响
过度声明列宽会产生很大差异的另一种情况是,是否将使用SSIS处理表。分配给可变长度(非BLOB)列的内存对于执行树中的每一行都是固定的,并且是根据列的声明最大长度而定的,这可能导致内存缓冲区的使用效率低下(示例)。尽管SSIS包开发人员可以声明比源更小的列大小,但最好是预先进行分析并在那里执行。
回到SQL Server引擎本身,类似的情况是在计算要分配给的内存授权时 SORT
操作 SQL Server假定varchar(x)
列平均将消耗x/2
字节。
如果您的大多数varchar
专栏文章都比这多,那可能会导致sort
操作溢出到tempdb
。
就您而言 varchar
列被声明为8000
字节,但是实际上所包含的内容远远少于查询所分配的内容,那么它不需要的内存显然是效率低下的,并且可能导致等待内存授予。
SQL Workshops网络广播1的第2部分对此进行了介绍,可从此处或从下面下载。
use tempdb;
CREATE TABLE T(
id INT IDENTITY(1,1) PRIMARY KEY,
number int,
name8000 VARCHAR(8000),
name500 VARCHAR(500))
INSERT INTO T
(number,name8000,name500)
SELECT number, name, name /*<--Same contents in both cols*/
FROM master..spt_values
SELECT id,name500
FROM T
ORDER BY number
SELECT id,name8000
FROM T
ORDER BY number