性能上没有区别。由于 2 的幂,没有进行任何隐藏的优化。
唯一对事物的存储方式产生影响的是实际数据。存储在VARCHAR2(2000)
列中的 100 个字符的存储方式与存储在列中的 100 个字符完全相同VARCHAR2(500)
。
将长度视为业务约束,而不是数据类型的一部分。唯一应该驱动您决定长度的是关于放入其中的数据的业务限制。
编辑:长度确实有所不同的唯一情况是当您需要该列的索引时。较旧的 Oracle 版本 (< 10) 确实对密钥长度有限制,并且在创建索引时会检查该限制。
尽管在 Oracle 11 中是可能的,但对具有 4000 个字符的值进行索引可能不是最明智的选择。
编辑 2:
所以我很好奇并设置了一个简单的测试:
create table narrow (id varchar(40));
create table wide (id varchar(4000));
然后用由 40 个“X”组成的字符串填充两个表。如果存储之间确实存在(实质性)差异,那么在检索数据时应该会以某种方式显示出来,对吧?
两个表都有 1048576 行。
连接到:
Oracle Database 11g 企业版 11.2.0.3.0 - 64 位生产
具有分区、OLAP、数据挖掘和实际应用程序测试选项
SQL> 设置自动跟踪 traceonly 统计信息
SQL> select count(*) from wide;
统计数据
-------------------------------------------------- --------
0 次递归调用
1 db 块获取
6833 一致获得
0 次物理读取
0 重做大小
通过 SQL*Net 向客户端发送 349 个字节
通过 SQL*Net 从客户端收到 472 个字节
2 次 SQL*Net 往返客户端
0 种(内存)
0 种(磁盘)
已处理 1 行
SQL> 从窄中选择计数(*);
统计数据
-------------------------------------------------- --------
0 次递归调用
1 db 块获取
6833 一致获得
0 次物理读取
0 重做大小
通过 SQL*Net 向客户端发送 349 个字节
通过 SQL*Net 从客户端收到 472 个字节
2 次 SQL*Net 往返客户端
0 种(内存)
0 种(磁盘)
已处理 1 行
SQL>
因此,两个表的全表扫描完全相同。那么当我们实际选择数据时会发生什么?
SQL> 从宽中选择 *;
选择了 1048576 行。
统计数据
-------------------------------------------------- --------
4个递归调用
2 db 块获取
76497 一致获取
0 次物理读取
0 重做大小
54386472 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 769427 个字节
69907 SQL*Net 往返客户端
0 种(内存)
0 种(磁盘)
处理了 1048576 行
SQL> 从窄中选择 *;
选择了 1048576 行。
统计数据
-------------------------------------------------- --------
4个递归调用
2 db 块获取
76485 一致获取
0 次物理读取
0 重做大小
54386472 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 769427 个字节
69907 SQL*Net 往返客户端
0 种(内存)
0 种(磁盘)
处理了 1048576 行
SQL>
一致的获取略有不同,但这可能是由于缓存。