sql - 定义最佳 varchar 长度

标签 sql sql-server sqldatatypes

我发现varchar(20)varchar(40)在性能方面没有区别。

但后来我从逻辑上问自己一个问题,为什么不创建一个所有字符列都为 varchar(4000) 的表?

在我看来,如果我的列仅包含 3 个字符,则 varchar(3)varchar(4000) 之间存在一些区别。但我找不到这种区别。

最佳答案

存储空间与 Microsoft 文档中定义的没有区别。

varchar [ ( n | max ) ] Variable-length, non-Unicode string data. n defines the string length and can be a value from 1 through 8,000. max indicates that the maximum storage size is 2^31-1 bytes (2 GB). The storage size is the actual length of the data entered + 2 bytes. The ISO synonyms for varchar are char varying or character varying. http://technet.microsoft.com/en-us/library/ms176089.aspx

您所拥有的差异是可能会出现不良数据。列应定义为允许最大有效输入,而不仅仅是允许任何内容。我曾见过 VARCHAR(MAX) 列导致数据库崩溃,因为有人运行了错误的更新语句,并用近 2 GB 的数据填充了每一行。

运行以下查询并查看执行计划。

DECLARE @tableOne TABLE
(
 id INT
,MySmallField VARCHAR(3)
)

DECLARE @tabletwo TABLE
(
 id INT
,MyBigField VARCHAR(3000)
)

INSERT INTO @tableOne
VALUES( 0, 'aaa' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 5, 'ddd' )

INSERT INTO @tableTwo
VALUES( 0, 'aaa' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 1, 'aaa' ),( 2, 'aaa' ),( 3, 'bbb' ),( 4, 'ccc' ),( 5, 'ddd' ),( 5, 'ddd' )


SELECT * FROM @tableOne WHERE MySmallField = 'ccc'

SELECT * FROM @tabletwo WHERE MyBigField = 'ccc'

下载SQL Sentry Plan Explorer它是免费工具,为您提供比 SSMS 更易于使用的界面。

查看一个简单语句的执行计划,您会发现为了插入大列,sql server 添加了 Compute Scalar 函数,该函数执行以下操作

Expr1104=CONVERT_IMPLICIT(varchar(3000),[Union1103],0 

对于此操作,数据站点从 784 B 上升到 74 KB。仅插入 50 行即可完成此操作。操作越大,影响就越大。

关于sql - 定义最佳 varchar 长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22689989/

相关文章:

sql - 比较 varchar 列中的十进制值

c++ - 使用带有 wxWidgets 的 mysql lib 的类崩溃

Mysql多重连接语法错误

sql - MS SQL 临时表

asp.net - 应用程序未连接到防火墙外部的sqlserver

mysql - 存储经度和纬度值需要哪种数据类型

mysql - 有两个条件的两个字段的选择

sql - 这两个查询有什么区别?

sql - 用于根据列类型插入默认值的存储过程

c++ - 从 double 创建 std::chrono::high_resolution_clock::time_point ?