【问题标题】:Oracle preferred columns lengthsOracle 首选列长度
【发布时间】:2013-01-17 17:38:29
【问题描述】:

列长度的乘数是否会以某种方式影响数据库性能?

也就是说,下面两张表的表现有什么区别:

TBL1:
  - CLMN1 VARCHAR2(63)
  - CLMN2 VARCHAR2(129)
  - CLMN3 VARCHAR2(250)

TBL2:
  - CLMN1 VARCHAR2(64)
  - CLMN2 VARCHAR2(128)
  - CLMN3 VARCHAR2(256)

我们是否应该始终尝试使列的长度达到2 的某个幂,还是只考虑最大大小?

一些开发人员声称数据库中列长度的乘法因子之间存在某种联系,因为它影响 Oracle 如何在磁盘上分配和保存数据以及共享其在内存中的缓存。有人可以证明或反驳这一点吗?

【问题讨论】:

  • 你试过性能测试了吗?
  • 没有。我想知道如果存在差异,理论上的解释是什么。因为很多时候开发人员喜欢分配二进制供电的列长度(64、128 ...)。我想知道为什么?它真的会以某种方式影响吗?
  • 您认识的开发人员可能正在考虑哈希分区it's recommended that the number of partitions is a power of 2
  • @Ben 谢谢你,这是一篇有价值的文章。但我还不明白:这个分区和列长度之间有什么联系吗?
  • 无@Andremoniy,这就是为什么这不是答案。我猜您认识的开发人员可能将分区与列长度混淆,因此(我没有对此进行测试或看到任何表明它是对/错的东西,尽管我相信 i> 这是错误的)

标签: oracle database-design database-performance


【解决方案1】:

性能没有区别。由于 2 的幂,没有进行任何隐藏的优化。

对事物的存储方式产生影响的唯一因素是实际数据。存储在 VARCHAR2(2000) 列中的 100 个字符的存储方式与存储在 VARCHAR2(500) 列中的 100 个字符完全相同。

将长度视为业务约束,而不是数据类型的一部分。唯一应该驱动您决定长度的是关于放入其中的数据的业务限制。

编辑:长度确实会产生影响的唯一情况是,当您需要在该列上建立索引时。较旧的 Oracle 版本 (

尽管在 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>

一致获取略有不同,但这可能是由于缓存造成的。

【讨论】:

  • 好的。所以,您声称,列长度对 Oracle 如何在磁盘上分配数据库文件和在内存中的数据库缓存没有任何影响,所以乘法因子没有任何意义?
  • 只有数据的实际长度会影响这一点,而不是声明的最大长度。 (当然还有其他配置属性,例如 PCTFREE)
  • @kevtufc:是的,这就是我要说的。不过要记住一件事:索引。我已经编辑了我的问题。
  • @Plouf!亲爱的,我并没有最小化a_horse_with_no_name 的权限。我只是想等待另一个意见和评价。此外,我想对这个问题进行理论证实。否则,如果有人会问我:你为什么这么认为? - 我的回答是:“a_horse_with_no_name 这么说”没有任何意义:)
  • 我知道 VARCHAR2 的大小有什么不同的唯一其他情况是在 PL/SQL 中使用它们时 - 基于列分配给变量的内存量取决于它们是否大于或小于一个临界点(以前是 2000,现在我相信是 4000)。
猜你喜欢
  • 1970-01-01
  • 2011-03-22
  • 2012-01-20
  • 1970-01-01
  • 1970-01-01
  • 2021-07-06
  • 2021-08-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多