none
数据类型varchar(n)、nvarchar(n)中n的大小会影响性能吗? RRS feed

答案

  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。

    揭晓答案:convert少了12个字节,是因为convert的结果,少了remark这个字段名,字段名是sysname类型的,6个字符正好12个字节。

    要是select CONVERT(varchar(108),remark) as remark from oswica_test的话,和select remark from oswica_test的字节数就完全一样了。

    所以说,varchar后面的数字,完全不影响结果字节数,石头的这个测试结果是不正确的。


    想不想时已是想,不如不想都不想。

    2012年8月30日 13:46
    版主

全部回复

  • 必须,处理1字节和10000000字节,所耗IO、内存、CPU肯定不同

    Try SQL Server 2008 QQ:315054403 dgdba@hotmail.com

    2012年8月27日 0:51
  • 考虑到sql 是以8k一个页来存储数据,所以当一个记录(不是一个字段,所有字段长度和)的长度超过这个值,就要分开存储在不同页上,这个将严重降低性能。

    你可以试试建立2张表多一个对比。


    family as water

    2012年8月27日 1:01
  • 如果你指的仅仅是设计表时的大小,这个几乎不影响性能。max稍有点不同,不过影响也不大。

    想不想时已是想,不如不想都不想。

    2012年8月27日 2:09
    版主
  • Will affect performance if n is smaller than certain number.
    2012年8月27日 3:33
  • 个人认为对性能的影响还是很小的, max除外!
    2012年8月27日 5:13
    版主
  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    2012年8月27日 8:17
  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。

    2012年8月27日 15:05
    版主
  • sql对于可变长度字段是单独存放的,对于可变长度截断的办法能够减少的网络流量有限。


    family as water

    2012年8月28日 2:12
  • 你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。


    是因为用CONVERT() 的关系吗?

    Learning SQL.

    2012年8月28日 2:40
  • 单从设计上来说不会有什么影响,要看具体存储的数据而定,如果数据都是定长的,那varchar(n)、nvarchar(n)肯定不如char(n)、nchar(n)的性能好
    2012年8月29日 1:41
  • 关注一下

    给我写信: QQ我:点击这里给我发消息

    2012年8月29日 16:54
  • 这个只有结合实际的值才能估计呢,vardata的n只不过是一个上限,在page中layout会有一些额外的字节来表明该行数据的该字段具体有多长。

    所以呢,只需考虑能不能装下所有的实际值,无需考虑page空间的利用率问题,因为你没法知道!

    ps:如果要用该字段建立索引,那就另当别论了,越小越好,最好不要

    2012年8月30日 6:44
  • 这个问题我觉得看你的使用场景,这里有一篇文章说得很详细:http://www.cnblogs.com/yelaiju/archive/2010/05/29/1746826.html

    在建表的时候你要知道字段实际存放的数据是什么数据如果是固定的,比如人名:那么可以使用 nchar(8) (两个字节存放一个汉字)

    尽量使用合适的数据类型,如果不是的话就会如楼上所说造成页分裂,增加逻辑读次数


    给我写信: QQ我:点击这里给我发消息

    2012年8月30日 9:12
  • 这个问题我觉得看你的使用场景,这里有一篇文章说得很详细:http://www.cnblogs.com/yelaiju/archive/2010/05/29/1746826.html

    在建表的时候你要知道字段实际存放的数据是什么数据如果是固定的,比如人名:那么可以使用 nchar(8) (两个字节存放一个汉字)

    尽量使用合适的数据类型,如果不是的话就会如楼上所说造成页分裂,增加逻辑读次数


    给我写信: QQ我:点击这里给我发消息


    基本上,设计时varchar后面是几,跟页分裂无关。楼上说的是数据有多少,不是数据类型的问题。

    想不想时已是想,不如不想都不想。

    2012年8月30日 13:40
    版主
  • 这个问题我觉得看你的使用场景,这里有一篇文章说得很详细:http://www.cnblogs.com/yelaiju/archive/2010/05/29/1746826.html

    在建表的时候你要知道字段实际存放的数据是什么数据如果是固定的,比如人名:那么可以使用 nchar(8) (两个字节存放一个汉字)

    尽量使用合适的数据类型,如果不是的话就会如楼上所说造成页分裂,增加逻辑读次数


    给我写信: QQ我:点击这里给我发消息


    另外,很遗憾的告诉你,你显然没弄明白nchar后面数字的含义。再说一次,看联机丛书的时候仔细一点。

    想不想时已是想,不如不想都不想。

    2012年8月30日 13:41
    版主
  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。

    揭晓答案:convert少了12个字节,是因为convert的结果,少了remark这个字段名,字段名是sysname类型的,6个字符正好12个字节。

    要是select CONVERT(varchar(108),remark) as remark from oswica_test的话,和select remark from oswica_test的字节数就完全一样了。

    所以说,varchar后面的数字,完全不影响结果字节数,石头的这个测试结果是不正确的。


    想不想时已是想,不如不想都不想。

    2012年8月30日 13:46
    版主
  • 怡红公子说的varchar后面的数字,完全不影响结果字节数,我觉得是的,因为varchar是不定长的,所以存多少就是多少,

    不像char(n),存多少都是n大小
    SQLSERVER数据类型:

    varchar英文一个字节,中文两个字节,nvarchar不管是英文中文都是两个字  

    nvarchar支持unicode不会乱码



    给我写信: QQ我:点击这里给我发消息

    2012年8月30日 14:49
  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。

    揭晓答案:convert少了12个字节,是因为convert的结果,少了remark这个字段名,字段名是sysname类型的,6个字符正好12个字节。

    要是select CONVERT(varchar(108),remark) as remark from oswica_test的话,和select remark from oswica_test的字节数就完全一样了。

    所以说,varchar后面的数字,完全不影响结果字节数,石头的这个测试结果是不正确的。


    想不想时已是想,不如不想都不想。


    那个无聊的实验只是说明不同字段类型以及宽度在查询中对网络带宽占用情况,从这个角度反映出字段类型宽度对系统性能产生的影响。至于你说的测试结果是否正确,所有测试数据都是有脚本存在,大家可以验证。

    family as water

    2012年8月31日 1:58
  • 怡红公子说的varchar后面的数字,完全不影响结果字节数,我觉得是的,因为varchar是不定长的,所以存多少就是多少,

    不像char(n),存多少都是n大小
    SQLSERVER数据类型:

    varchar英文一个字节,中文两个字节,nvarchar不管是英文中文都是两个字  

    nvarchar支持unicode不会乱码



    给我写信: QQ我:点击这里给我发消息

    你要看联机丛书,那个内容相对完整,正确。nchar(8) 是放8个汉字,不是4个汉字。

    nchar [ ( n ) ]

    n 个字符的固定长度的 Unicode 字符数据。n 值必须在 1 到 4,000 之间(含)。存储大小为两倍 n 字节。


    想不想时已是想,不如不想都不想。

    2012年8月31日 3:23
    版主
  • 无聊的时候做的一个测试

    http://oswica.blog.51cto.com/756561/475837

    字段宽度不同的时候对网络流量的影响。

    有功夫的同学可以看看对IO 等其他的影响。


    family as water

    你如果测试再深入一点就会发现。你建表的时候,用varchar(108)或者varchar(8000),返回的结果字节数都是一样的。

    为什么select CONVERT(varchar(108),remark) from oswica_test  会少12个字节呢?其实不是字段长度的关系,仔细想想,看你能不能发现少在什么地方。提示一下,少的其实是6个字符。


    想不想时已是想,不如不想都不想。

    揭晓答案:convert少了12个字节,是因为convert的结果,少了remark这个字段名,字段名是sysname类型的,6个字符正好12个字节。

    要是select CONVERT(varchar(108),remark) as remark from oswica_test的话,和select remark from oswica_test的字节数就完全一样了。

    所以说,varchar后面的数字,完全不影响结果字节数,石头的这个测试结果是不正确的。


    想不想时已是想,不如不想都不想。


    那个无聊的实验只是说明不同字段类型以及宽度在查询中对网络带宽占用情况,从这个角度反映出字段类型宽度对系统性能产生的影响。至于你说的测试结果是否正确,所有测试数据都是有脚本存在,大家可以验证。

    family as water


    你的几个脚本返回的内容就不一样,当然字节数不同了。

    想不想时已是想,不如不想都不想。

    2012年8月31日 3:23
    版主
  • 我也同意没有影响,我是把自己当做sql server来考虑这个问题的。
    2012年8月31日 3:26
  • @怡红公子

    观察细微啊,这个都被你发现了。

    2012年8月31日 5:46
  • 摘录自sql2005联机丛书
    字符数据类型(nchar 长度固定,nvarchar 长度可变)和 Unicode 数据使用 UNICODE UCS-2 字符集。 

    nchar [ ( n ) ]

    n 个字符的固定长度的 Unicode 字符数据。n 值必须在 1 到 4,000 之间(含)。存储大小为两倍 n 字节。nchar 的 SQL-2003 同义词为 national char 和 national character。

    nvarchar [ ( n | max ) ] 

    可变长度 Unicode 字符数据。n 值在 1 到 4,000 之间(含)。max 指示最大存储大小为 2^31-1 字节。存储大小是所输入字符个数的两倍 + 2 个字节。所输入数据的长度可以为 0 个字符。nvarchar 的 SQL-2003 同义词为 national char varying 和 national character varying。

    备注
    如果没有在数据定义或变量声明语句中指定 n,则默认长度为 1。如果没有使用 CAST 函数指定 n,则默认长度为 30。

    如果列数据项的大小可能相同,请使用 nchar。

    如果列数据项的大小可能差异很大,请使用 nvarchar。

    sysname 是系统提供的用户定义数据类型,除了不以为零外,在功能上与 nvarchar(128) 相同。sysname 用于引用数据库对象名





    固定长度或可变长度的字符数据类型。 

    char [ ( n ) ] 
    固定长度,非 Unicode 字符数据,长度为 n 个字节。n 的取值范围为 1 至 8,000,存储大小是 n 个字节。char 的 SQL 2003 同义词为 character。

    varchar [ ( n | max ) ] 
    可变长度,非 Unicode 字符数据。n 的取值范围为 1 至 8,000。max 指示最大存储大小是 2^31-1 个字节。存储大小是输入数据的实际长度加 2 个字节。所输入数据的长度可以为 0 个字符。SQL-2003 中的 varchar 就是 char varying 或 character varying。

    备注
    如果未在数据定义或变量声明语句中指定 n,则默认长度为 1。如果在使用 CAST 和 CONVERT 函数时未指定 n,则默认长度为 30。

    将为使用 char 或 varchar 的对象指派数据库的默认排序规则,除非使用 COLLATE 子句指派了特定的排序规则。该排序规则控制用于存储字符数据的代码页。

    如果站点支持多语言,请考虑使用 Unicode nchar 或 nvarchar 数据类型,以最大限度地消除字符转换问题。如果使用 char 或 varchar,建议执行以下操作: 

    如果列数据项的大小一致,则使用 char。


    如果列数据项的大小差异相当大,则使用 varchar。


    如果列数据项大小相差很大,而且大小可能超过 8,000 字节,请使用 varchar(max)。

    给我写信: QQ我:点击这里给我发消息

    2012年8月31日 12:45
  • 想问一下怡红公子,@a varchar(10)这个变量可以输入多少个字符呢?中文是多少个,英文是多少个?

    给我写信: QQ我:点击这里给我发消息


    2012年8月31日 12:50
  • 想问一下怡红公子,@a varchar(10)这个变量可以输入多少个字符呢?中文是多少个,英文是多少个?

    给我写信: QQ我:点击这里给我发消息



    你觉得呢?想一想,然后做一下测试,看看你想得对不对。

    想不想时已是想,不如不想都不想。

    2012年8月31日 15:15
    版主
  • 我知道是5个字符,我以为你又叫我去看联机丛书呢


    给我写信: QQ我:点击这里给我发消息

    2012年8月31日 15:39
  • 测试的sql语句以及结果

    DECLARE @a CHAR(6)
    SET @a='您啊啊啊啊是'
    PRINT 'char:'+@a
    
    DECLARE @b CHAR(6)
    SET @b='abcdefg'
    PRINT 'char:'+@b
    -----------------------
    
    DECLARE @c NCHAR(6)
    SET @c='您啊啊啊啊是'
    PRINT 'nchar:'+@c
    
    DECLARE @d NCHAR(6)
    SET @d='abcdefg'
    PRINT 'nchar:'+@d
    ------------------------------
    
    DECLARE @e VARCHAR(6)
    SET @e='您啊啊啊啊是'
    PRINT 'varchar:'+@e
    
    DECLARE @f VARCHAR(6)
    SET @f='abcdefg'
    PRINT 'varchar:'+@f
    --------------------------------
    DECLARE @g NVARCHAR(6)
    SET @g='您啊啊啊啊是'
    PRINT 'nvarchar:'+@g
    
    DECLARE @h NVARCHAR(6)
    SET @h='abcdefg'
    PRINT 'nvarchar:'+@h
    

    char:您啊啊
    char:abcdef
    nchar:您啊啊啊啊是
    nchar:abcdef
    varchar:您啊啊
    varchar:abcdef
    nvarchar:您啊啊啊啊是
    nvarchar:abcdef

    给我写信: QQ我:点击这里给我发消息

    2012年8月31日 15:59
  • 有时候真的要自己去测试,联机丛书都没有写存储多少个汉字

    给我写信: QQ我:点击这里给我发消息

    2012年8月31日 16:01
  • 有时候真的要自己去测试,联机丛书都没有写存储多少个汉字

    给我写信: QQ我:点击这里给我发消息


    Really well done!

    想不想时已是想,不如不想都不想。

    2012年9月3日 15:38
    版主
  • DECLARE @a CHAR(6)
    SET @a='您啊啊啊啊是'
    PRINT 'char:'+@a
    
    DECLARE @b CHAR(6)
    SET @b='abcdefg'
    PRINT 'char:'+@b
    
    DECLARE @c CHAR(6)
    SET @c='123456'
    PRINT 'char:'+@c
    -----------------------
    
    DECLARE @d NCHAR(6)
    SET @d='您啊啊啊啊是'
    PRINT 'nchar:'+@d
    
    DECLARE @e NCHAR(6)
    SET @e='abcdefg'
    PRINT 'nchar:'+@e
    
    DECLARE @f NCHAR(6)
    SET @f='123456'
    PRINT 'nchar:'+@f
    ------------------------------
    
    DECLARE @g VARCHAR(6)
    SET @g='您啊啊啊啊是'
    PRINT 'varchar:'+@g
    
    DECLARE @h VARCHAR(6)
    SET @h='abcdefg'
    PRINT 'varchar:'+@h
    
    DECLARE @i VARCHAR(6)
    SET @i='123456'
    PRINT 'varchar:'+@i
    --------------------------------
    DECLARE @j NVARCHAR(6)
    SET @j='您啊啊啊啊是'
    PRINT 'nvarchar:'+@j
    
    DECLARE @k NVARCHAR(6)
    SET @k='abcdefg'
    PRINT 'nvarchar:'+@k
    
    DECLARE @l NVARCHAR(6)
    SET @l='123456'
    PRINT 'nvarchar:'+@l

    结果:

    char:您啊啊
    char:abcdef
    char:123456
    nchar:您啊啊啊啊是
    nchar:abcdef
    nchar:123456
    varchar:您啊啊
    varchar:abcdef
    varchar:123456
    nvarchar:您啊啊啊啊是
    nvarchar:abcdef
    nvarchar:123456


    给我写信: QQ我:点击这里给我发消息

    2012年9月4日 3:54