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


当前回答

我的测试表明,在选择时存在差异。

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;

其他回答

数据库的任务是存储数据,以供企业使用。让数据有用的一部分是确保它是有意义的。允许用户为自己的名字输入无限个字符并不能确保数据有意义。

将这些约束构建到业务层是一个好主意,但这并不能确保数据库保持完整。保证数据规则不被违反的唯一方法是在数据库中尽可能低的级别执行它们。

我的测试表明,在选择时存在差异。

CREATE TABLE t4000 (a NVARCHAR(4000) NULL);

CREATE TABLE tmax (a NVARCHAR(MAX) NULL);

DECLARE @abc4 NVARCHAR(4000) = N'ABC';

INSERT INTO t4000
SELECT TOP 1000000 @abc4
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

DECLARE @abc NVARCHAR(MAX) = N'ABC';

INSERT INTO tmax
SELECT TOP 1000000 @abc
    FROM
    master.sys.all_columns ac1,
    master.sys.all_columns ac2;

SET STATISTICS TIME ON;
SET STATISTICS IO ON;

SELECT * FROM dbo.t4000;
SELECT * FROM dbo.tmax;

当你知道字段将在一个固定的范围内时,这不是一个好主意——例如5到10个字符。我想我只会在不确定长度的情况下使用max。例如,电话号码永远不会超过一定数量的字符。

你能诚实地说,你不确定表中每个字段的大约长度要求吗?

我确实明白你的意思——有些字段我肯定会考虑使用varchar(max)。

有趣的是,MSDN文档总结得很好:

的大小时使用varchar 列数据条目变化很大。 的大小时使用varchar(max) 列数据条目变化很大, 大小可能超过8000字节。

关于这个问题有一个有趣的讨论。

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

一个问题是,如果你必须使用多个版本的SQL Server, MAX并不总是有效的。因此,如果您正在使用遗留DB或涉及多个版本的任何其他情况,您最好非常小心。