我有一些使用 Entity Framework Code First 创建的数据库;应用程序正在运行,总的来说,我对 Code First 让我做的事情感到非常满意。我首先是一名程序员,其次是 DBA,这是必要的。我正在阅读 DataAttributes 以在 C# 中进一步描述我希望数据库执行的操作;我的问题是:将这些nvarchar(max)字符串放在我的桌子上会吃什么惩罚(见下面的例子)?
在这个特定的表中有几列;在 C# 中,它们是这样定义的:
[Key]
[DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
public int ID { get; set; }
public string Name { get; set; }
public string Message { get; set; }
public string Source { get; set; }
public DateTime Generated { get; set; }
public DateTime Written { get; set; }
Run Code Online (Sandbox Code Playgroud)
我希望根据名称、来源、生成和书面内容进行查询和/或排序。我希望 Name 和 Source 的长度为 0-50 个字符,有时可达 150 个。我希望这个表开始时很小(<100k 行),但随着时间的推移显着增长(>1m 行)。显然消息可以是小或大的,并且可能不会被查询。
我想知道的是,我的 Name 和 Source …
sql-server entity-framework sql-server-2008-r2 azure-sql-database
由于 varchar 占用的磁盘空间与字段的大小成正比,有什么理由我们不应该总是将 varchar 定义为最大值,例如varchar(8000)在 SQL Server 上?
在创建表上,如果我看到有人在做varchar(100)我应该告诉他们不你错了你应该做什么varchar(8000)?
在将数据导入到 SQL Server 时,人们通常无法考虑导入的字符串字段有多大。我是否可以懒惰地继续对 char 字段定义使用较大的值?如果我花精力寻找合适的 char 字段最大大小,它会对性能和速度产生任何影响吗?
如果重要的话,我有 SQL Server 2016 和 2019。
(我不认为这个问题是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 文章描述相同?