定义具有更大长度的 VARCHAR2 列的影响

Posted

技术标签:

【中文标题】定义具有更大长度的 VARCHAR2 列的影响【英文标题】:Impact of defining VARCHAR2 column with greater length 【发布时间】:2010-12-25 07:43:00 【问题描述】:

在Oracle中用VARCHAR2(1000)而不是VARCHAR2(10)定义列,当值不超过10字节时有什么影响?

列是否只占用存储值真正需要的空间,还是会对表空间/索引的大小/性能产生任何负面影响?

【问题讨论】:

【参考方案1】:

答案取决于您是在谈论数据库表中的列,还是 PL/SQL 程序中的变量。

数据库列

使用的存储量与存储的数据大小成正比。

PL/SQL 变量

如果声明变量的大小为 1 到 4000 (11g+) / 1999(10g 或更早),则内存将分配为最大长度(即 VARCHAR2(100) 将需要至少 100 字节的内存)。

如果变量声明的大小为 4001 (11g+) / 2000 (10g 或更早) 或更大,则将根据存储的数据大小分配内存。 (一个有趣的问题是,如果变量的值改变了,内存是如何调整大小的——它会重新分配另一个具有新大小的缓冲区吗?)

10g参考:PL/SQL Datatypes

较小的 VARCHAR2 变量针对性能进行了优化,较大的变量针对有效的内存使用进行了优化。截止点是 2000 字节。对于 2000 字节或更长的 VARCHAR2,PL/SQL 仅动态分配足够的内存来保存实际值。对于小于 2000 字节的 VARCHAR2 变量,PL/SQL 会预先分配变量的完整声明长度。例如,如果将相同的 500 字节值分配给 VARCHAR2(2000 BYTE) 变量和 VARCHAR2(1999 BYTE) 变量,则前者占用 500 字节,后者占用 1999 字节。

11g 参考:Avoiding Memory Overhead in PL/SQL Code

为 VARCHAR2 变量指定 超过 4000 个字符的大小; PL/SQL 一直等到您分配变量,然后才根据需要分配尽可能多的存储空间

【讨论】:

我说的是表列,但是 PL/SQL 参考也很有趣,谢谢! (+1) 没错 - 请注意,当您开始编写与表数据交互的 PL/SQL 代码时,它变得更加相关 - 即您可能倾向于声明与数据库列大小相同的 VARCHAR2 变量.当然,这个内存使用因素是 IMO 在列和变量大小方面最不重要的考虑因素。 在 PL/SQL 问题上,PL/SQL 动态分配内存的截止点已随版本而变化。例如,在 10g 中它从 增加到 2000,但在 11.1 中增加到 4000。见download.oracle.com/docs/cd/B28359_01/appdev.111/b28370/…【参考方案2】:

在数据库中,没有区别。 VARCHAR2 以可变长度存储,声明的长度只是一个限制。

但是,如果某些客户端应用程序看到列被定义为 VARCHAR2(1000),则会为每列保留 1000 字节而不是 10

【讨论】:

【参考方案3】:

将列大小定义为您准备处理的最大长度。 对于临时表,我将文件加载到数据库中,我可以使用 VARCHAR2(4000)。然后,一旦所有数据都在数据库中,我就可以进行所需的任何验证(数据类型、数据长度、最小/最大值、可接受的字符......)并将有效值传递到具有适当定义的列中/约束。

我可以利用DML error logging 将不符合定义/约束的数据抽到拒绝表中,而无需任何棘手的逐行编码。

如果你有一个 VARCHAR2(1000) 那么,在某些时候你会得到比你预期更长的数据(例如,你可能会得到一个 10 个字符的字符串,但它有 14 个字节,因为有些字符是多字符的字节字符集值。)

【讨论】:

以上是关于定义具有更大长度的 VARCHAR2 列的影响的主要内容,如果未能解决你的问题,请参考以下文章

设计数据库表时要不要定义字段的长度?指定字段长度和不指定长度有啥区别?

Oracle LOB类型

oracle两个表varchar2长度不一致会走索引吗?还有char型和varchar2型的字段关联会走索引吗?

char varchar varchar2 的区别 (转)

表的循环列的Oracle结构

oracle中字段类型varchar2最大长度是多少?