(我不相信这个问题是8 年前这个问题的重复,因为我不是在问超大列的优势,我问的是下面链接文章中展示的行为。)
SQLPerformance.com 的这篇最近 (2017) 文章演示了改变列的最大长度如何n
影响varchar(n)
查询计划行大小估计和排序缓冲区大小估计,从而导致性能不佳和内存分配警告。
在其中,作者声称(强调我的):
从这里我们看到,列定义越大,估计的行和数据大小就越大。在这个简单的查询中,无论定义如何,所有查询的 I/O 成本 (0.0512731) 都是相同的,因为聚集索引扫描无论如何都必须读取所有数据。
但在其他情况下,估计的行和总数据大小会产生影响:需要额外资源的操作,例如排序。
当我读到该声明(粗体)时,我感到很惊讶,因为我认为 SQL Server 会从STATISTICS
维护在这些相同表上的采样对象中获得相当准确的行大小估计。特别是考虑到SELECT AVG(LEN(email))
文章中的查询显示没有列的值超过 77 个字符。
这篇文章还明确地执行了一个ALTER INDEX ALL ON dbo.Table REBUILD
-这个 DB.SE 帖子说也将自动更新STATISTICS
。
(虽然我很惊讶 SQLPerformance 文章中根本没有出现“统计”这个词 - 所以在作者的情况下,由于某些机器配置,统计数据可能根本没有更新,他们没有注意到?)
SQL Server 是否仅将varchar
列长度限制用于行大小估计?如果不是,那么为什么 SQLPerformance 文章描述相同?
正确的。SQL Server 在估计行大小时仅使用 varchar(指定的最大值)长度。SQLPerformance 文章准确地描述了估计的行大小测量。
更长的答案
在链接文章的示例中,Aaron 重建了所有索引,以确保所有版本的查询在索引大小和统计数据方面都具有平等的竞争环境,因此所有案例的执行计划都是“理想的”并且(如实验证明的那样) )几乎相等,但不完全相等。
统计信息用于估计将返回多少行,而不是为执行查询授予多少内存。
在文章中,亚伦说(强调我的):
Aaron 对“直方图步长值”的引用是对统计直方图的引用。统计直方图包含表中最多 201 个数据值的知识。它知道那些(最多 201 个)显式值的实际长度,但它不知道这些值之间的值。
此外,统计数据基于数据样本,因此可能有一些行没有作为样本的一部分进行分析,并且依赖于统计数据的最小/最大/平均长度将是过时或不具代表性的样本产生不利影响的另一个机会影响查询执行。