在SQL Server 2005中,将所有字符字段设置为nvarchar(MAX)而不是显式指定长度(例如nvarchar(255))有什么缺点吗?(除了不能在数据库级别限制字段长度之外)


当前回答

一个缺点是,您将围绕一个不可预知的变量进行设计,您可能会忽略而不是利用内部SQL Server数据结构,逐步由Row(s)、Page(s)和Extent(s)组成。

这让我想到了C中的数据结构对齐,并且通常认为知道对齐是一件好事(TM)。相似的想法,不同的背景。

页面和区段的MSDN页面

行溢出数据的MSDN页面

其他回答

根据已接受的答案中提供的链接,似乎是:

存储在nvarchar(MAX)字段中的100个字符将与存储在nvarchar(100)字段中的100个字符没有区别-数据将内联存储,并且您不会有“行外”读取和写入数据的开销。所以不用担心。 如果大小大于4000,数据将自动“行外”存储,这是你想要的。所以也不用担心。

然而……

不能在nvarchar(MAX)列上创建索引。可以使用全文索引,但不能在列上创建索引以提高查询性能。对我来说,这就决定了……总是使用nvarchar(MAX)是一个明显的缺点。

结论:

如果你想要一种贯穿整个数据库的“通用字符串长度”,它可以被索引,并且不会浪费空间和访问时间,那么你可以使用nvarchar(4000)。

有趣的链接:当你可以使用文本时,为什么要使用VARCHAR ?

它是关于PostgreSQL和MySQL的,所以性能分析是不同的,但是“显式”的逻辑仍然成立:为什么强迫自己总是担心一些在一小部分时间内相关的事情呢?如果你把一个电子邮件地址保存到一个变量中,你会使用一个“字符串”而不是一个“限制为80个字符的字符串”。

这将使屏幕设计变得更加困难,因为你将不再能够预测你的控制应该有多宽。

1)当处理nvarchar(max) vs nvarchar(n)时,SQL服务器将不得不利用更多的资源(分配的内存和cpu时间),其中n是一个特定于字段的数字。

2)就绩效而言,这意味着什么?

在SQL Server 2005上,我从一个有15个nvarchar(max)列的表中查询了13000行数据。 我重复计时查询,然后将列更改为nvarchar(255)或更小。

优化之前的查询平均为2.0858秒。更改后的查询平均返回时间为1.90秒。这比基本select *查询提高了约184毫秒。这一数字提高了8.8%。

3)我的结果与其他几篇文章一致,表明存在性能差异。根据数据库和查询的不同,改进的百分比可能有所不同。如果您没有很多并发用户或很多记录,那么性能差异对您来说不是问题。但是,随着记录和并发用户的增加,性能差异也会增加。

我能看到的主要缺点是,假设你有这样的情况:

哪一个提供了关于UI所需数据的最多信息?

This

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](MAX) NULL,
                [CompanyName] [nvarchar](MAX) NOT NULL,
                [FirstName] [nvarchar](MAX) NOT NULL,
                [LastName] [nvarchar](MAX) NOT NULL,
                [ADDRESS] [nvarchar](MAX) NOT NULL,
                [CITY] [nvarchar](MAX) NOT NULL,
                [County] [nvarchar](MAX) NOT NULL,
                [STATE] [nvarchar](MAX) NOT NULL,
                [ZIP] [nvarchar](MAX) NOT NULL,
                [PHONE] [nvarchar](MAX) NOT NULL,
                [COUNTRY] [nvarchar](MAX) NOT NULL,
                [NPA] [nvarchar](MAX) NULL,
                [NXX] [nvarchar](MAX) NULL,
                [XXXX] [nvarchar](MAX) NULL,
                [CurrentRecord] [nvarchar](MAX) NULL,
                [TotalCount] [nvarchar](MAX) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]

还是这个?

            CREATE TABLE [dbo].[BusData](
                [ID] [int] IDENTITY(1,1) NOT NULL,
                [RecordId] [nvarchar](50) NULL,
                [CompanyName] [nvarchar](50) NOT NULL,
                [FirstName] [nvarchar](50) NOT NULL,
                [LastName] [nvarchar](50) NOT NULL,
                [ADDRESS] [nvarchar](50) NOT NULL,
                [CITY] [nvarchar](50) NOT NULL,
                [County] [nvarchar](50) NOT NULL,
                [STATE] [nvarchar](2) NOT NULL,
                [ZIP] [nvarchar](16) NOT NULL,
                [PHONE] [nvarchar](18) NOT NULL,
                [COUNTRY] [nvarchar](50) NOT NULL,
                [NPA] [nvarchar](3) NULL,
                [NXX] [nvarchar](3) NULL,
                [XXXX] [nvarchar](4) NULL,
                [CurrentRecord] [nvarchar](50) NULL,
                [TotalCount] [nvarchar](50) NULL,
                [Status] [int] NOT NULL,
                [ChangeDate] [datetime] NOT NULL
            ) ON [PRIMARY]