首页 > 解决方案 > 解释为什么我们需要在 nvl(dbms_lob.getlength(column_name_blob),0) OR nvl(vsize(column_name),0) 上加 1

问题描述

当我遇到http://www.dba-oracle.com/t_find_length_clob.htm时,我正在寻找在 Oracle 中查找行的长度。任何人都可以解释为什么我们需要将 1 添加到nvl(dbms_lob.getlength(column_name_blob),0)ORnvl(vsize(column_name),0)吗?

像:

select
nvl(dbms_lob.getlength(CASE_DATA),0)+1 +
     nvl(vsize(CASE_NUMBER   ),0)+1 +
     nvl(vsize(CASE_DATA_NAME),0)+1 +
     nvl(vsize(LASTMOD_TIME_T),0)+1
     "Total bytes per row"
from
    mytab
where
    case = 123;

标签: oracle

解决方案


一行存储(或多或少)为

 [row header]
 [length of column1] [column1 data]
 [length of column2] [column2 data]
 [length of column3] [column3 data]
 ...

其中[row header]由 组成[flag byte][lock byte][columns count],即 3 个字节。

让我们看一个简单的例子——这是数据块转储中一行的转储信息:

tl: 44 fb: --H-FL-- lb: 0x1 cc: 3
col 0: [22]
 4d 61 6e 20 57 68 6f 20 53 6f 6c 64 20 54 68 65 20 57 6f 72 6c 64
col 1: [ 3] c2 14 47
col 2: [13] 42 6c 6f 6f 64 79 20 47 6f 6f 64 21 21

这里

  • tl- 行的总长度 - 44 字节 - oracle 不存储它,oracle 只是为我们计算了它
  • fb- 标志字节
  • lb- 锁定字节
  • cc- 列长
  • [N] - 列数据的长度
  • 以及之后的列数据

让我们手动计算这一行的长度:

  • 行头:标志字节 + 锁定字节 + 列数 = 3 字节
  • 第 0 列:列长(1 字节)+ 22 b = 23 字节
  • 第 1 列:列长(1 字节)+ 3 b = 4 字节
  • 第 2 列:列长(1 字节)+ 13 b = 14 字节

所以总 = 3 + 23 + 4 + 14 = 44 个字节,我们可以看到它等于tl,所以我们计算正确。

当然,在迁移或链接行的情况下,您将拥有更多行标题,因此您也需要添加它们的长度。

简而言之:您可以使用这个简化的公式:3(行标题)+列数+所有列值的 vsize(),例如,对于具有 3 列(没有 LOB)的表,考虑到空值:

select
   3 -- row header
  +nvl(vsize(col0),1) -- even if other columns are nulls too, null will be stored as 1 byte (0xFF)
  +nvl(vsize(col1), case when col2 is null then 0 else 1 end) -- 0 if there is no data after this column
  +nvl(vsize(col1),0) -- oracle doesn't store trailing NULL-valued columns in row
from t

但!这与 LOB 无关: 首先,它取决于ENABLE 或 DISABLE STORAGE IN ROW选项。

LOB 列存储引用实际 LOB 值位置的定位器。本节介绍如何启用或禁用表行中的存储。

实际 LOB 值存储在表行(内联)或表行外(外联),具体取决于您在创建表时指定的列属性以及 LOB 的大小。启用 | DISABLE STORAGE IN ROW 子句用于指示 LOB 应该是内联(行内)还是外联存储。

如果设置了 ENABLE STORAGE IN ROW,则该行中存储的最大 LOB 数据量为 4000 字节。这包括控制信息和 LOB 值。

因此,如果是Inline短 lob(<3960 字节),您可以计算它们的长度,但不能计算长 lob:首先,您需要计算 lob 定位器的长度 + lob 索引 + 计算存储数据和相乘所需的块的数量它在块大小上。并且不要忘记 LOB retention(或pctversion):您可能还需要计算 LOB 的旧版本


推荐阅读