列长度的倍增因子是否会以某种方式影响数据库性能?
换句话说,下面两个表的性能有什么区别:
TBL1:
- CLMN1 VARCHAR2(63)
- CLMN2 VARCHAR2(129)
- CLMN3 VARCHAR2(250)
和
TBL2:
- CLMN1 VARCHAR2(64)
- CLMN2 VARCHAR2(128)
- CLMN3 VARCHAR2(256)
我们是否应该总是尝试将列的长度设置为
2
的某个幂?还是只有最大尺寸很重要?一些开发人员声称数据库中列长度的倍增因子之间存在某种联系,因为它影响 Oracle 如何在磁盘上分配和保存数据以及在内存中共享其缓存。有人可以证明或反驳这一点吗?
最佳答案
性能没有区别。由于 2 的幂,没有进行隐藏的优化。
唯一对事物的存储方式产生影响的是实际数据。 100 个字符存储在 VARCHAR2(2000)
中列的存储方式与 VARCHAR2(500)
中存储 100 个字符的方式完全相同柱子。
将长度视为业务约束,而不是数据类型的一部分。唯一应该插入您决定长度的因素是有关放入其中的数据的业务限制。
编辑 :长度确实有所不同的唯一情况是当您需要该列上的索引时。较旧的 Oracle 版本 (< 10) 确实对键长度有限制,并在创建索引时进行了检查。
尽管在 Oracle 11 中是可能的,但在具有 4000 个字符的值上建立索引可能不是最明智的选择。
编辑 2 :
所以我很好奇并设置了一个简单的测试:
create table narrow (id varchar(40));
create table wide (id varchar(4000));
然后用由 40 个“X”组成的字符串填充两个表。如果存储之间确实存在(实质性)差异,那么在检索数据时应该会以某种方式显示出来,对吗?
两个表都正好有 1048576 行。
连接到:
Oracle 数据库 11g 企业版 11.2.0.3.0 版 - 64 位生产
使用分区、OLAP、数据挖掘和实际应用程序测试选项
SQL> 设置自动跟踪 traceonly 统计信息
SQL> select count(*) from wide;
统计数据
-------------------------------------------------- --------
0 递归调用
1 db 块获取
6833 一致获取
0 物理读取
0 重做大小
349 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 472 个字节
2 次 SQL*Net 往返客户端
0 排序(内存)
0 排序(磁盘)
已处理 1 行
SQL> 选择计数(*)从窄;
统计数据
-------------------------------------------------- --------
0 递归调用
1 db 块获取
6833 一致获取
0 物理读取
0 重做大小
349 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 472 个字节
2 次 SQL*Net 往返客户端
0 排序(内存)
0 排序(磁盘)
已处理 1 行
查询>
所以两个表的全表扫描完全一样。那么当我们实际选择数据时会发生什么呢?
SQL> select * from wide;
已选择 1048576 行。
统计数据
-------------------------------------------------- --------
4 次递归调用
2 db 块获取
76497 一致获取
0 物理读取
0 重做大小
54386472 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 769427 字节
69907 SQL*Net 往返客户端
0 排序(内存)
0 排序(磁盘)
已处理 1048576 行
SQL> select * from 窄;
已选择 1048576 行。
统计数据
-------------------------------------------------- --------
4 次递归调用
2 db 块获取
76485 一致获取
0 物理读取
0 重做大小
54386472 字节通过 SQL*Net 发送到客户端
通过 SQL*Net 从客户端收到 769427 字节
69907 SQL*Net 往返客户端
0 排序(内存)
0 排序(磁盘)
已处理 1048576 行
查询>
一致获取略有不同,但这可能是由于缓存造成的。
关于Oracle 首选列长度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14375250/