nchar与nvarchar性能比较

12
你如何决定使用nvarchar还是nchar?
例如,我注意到由sqlmembership提供程序创建的默认成员资格数据库将电子邮件列声明为nvarchar(256)类型。
对我来说,这似乎是电子邮件列的一个不必要的大最大值。我认为在正常情况下,长度超过40或50个字符的电子邮件应该很少见。
但是,由于诸如电子邮件地址之类的数据长度各异,它们是否应始终存储为nvarchar以消除冗余空间?
如果使用nvarchar作为电子邮件列。如果更改电子邮件地址,并且新电子邮件比先前的电子邮件长,是否会导致许多页面分割,从而产生性能成本?
您会考虑使用nchar(40)来代替电子邮件地址,以换取无页面分割性能成本而损失存储空间吗?
或者,使用nchar(40)会显着增加数据库大小,从而对查询速度造成其他性能影响吗?
“只有在知道要填充的列的数据大小时才使用nchar”是否是一个合理的遵循规则?

通常来说,任何少于5-10个字符的内容(比如货币符号USDGBP等或美国州名缩写AZME等)都可以使用定长的CHAR(x)NCHAR(x)类型。对于超过此长度的任何内容,我总是选择可变长度字符串 - 如果你有一个VARCHAR(255)并且大多数条目只有40-50个字符长,那么2字节的开销对于VARCHAR类型非常值得。 - marc_s
1个回答

12

超过40或50个字符的电子邮件是相当罕见的

只需要一个就足以破坏你的模型...

如果新电子邮件比之前的电子邮件长,会导致许多页面拆分吗?

不会。但即使如此,这也不是您设计数据模型的方式。假设为了争辩而言,每次更新电子邮件都会导致页面拆分。您会针对那个进行优化吗?否,因为预分配大型固定大小(即使用NCHAR(256))会更糟,它确实消除了潜在的更新页面拆分(再次,如果这样的页面拆分发生),但付出的代价远远更高,它增加了表格大小,从而转换为IO带宽和内存消耗,参见Disk space is cheap...THAT'S NOT THE POINT!!!

为什么我说可变长度更新不会导致页面拆分呢?因为当行图像不再适合页面时,将强制执行页面拆分。向可变长度列进行的更新可能会导致行溢出,并使行保持与之前相同的大小,甚至更小。在溢出后,行大小可能会增加,但是要触发页面拆分,必须满足以下几个条件:

  • 更新的值必须触发行大小的增加,这只能在从少于表格和索引组织中描述的24字节指针的值更新到大于此指针大小的值时发生。
  • 行大小的增加(根据定义,对于每个可变列的更新,包括从NULL到非NULL的更新,最多会增加24个字节的指针)必须导致行不适合该页面。
  • 不能通过将其他字段推送到行外来回收空间(即所有可变长度字段都已被推送到行外)
  • 我真的不相信你的工作条件如上所述是驱动你设计的主要因素,这么奇怪和深奥的工作量。使用一个方便长度的NVARCHAR来容纳你会遇到的任何值。

谢谢提供的信息和链接!我之前看过Kimberly L. Tripp的那篇文章,但再读一遍也很有益。对我来说,了解SQL Server如何处理行溢出等情况非常有用。所以再次感谢。 - Duncan Gravill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接