《早期博客迁移博文》
在Oracle数据库中有4种LOB类型:
CLOB,BLOB,NCLOB (stored internally to Oracle)
BFILE (stored externally)
若一张表包含LOB对象(CLOB,NCLOB,BLOB),那么Oracle就会为每一个LOB列创建两个数据段(segment),一个是LOBINDEX,一个是LOBSEGMENT。可通过ALL/USER/DBA_LOBS数据字典查看。
例如:
SQL> create table tst_lob02
2 (lob clob);
Table created.
SQL> run
1* select owner,column_name,segment_name,index_name from dba_lobs where table_name='TST_LOB02'
OWNER COLUMN_NAME SEGMENT_NAME INDEX_NAME
———- ——————– —————————— ——————————
LIGLE LOB SYS_LOB0000014030C00001$$ SYS_IL0000014030C00001$$
表tst_lob02含有一个lob字段,数据类型为CLOB,通过DBA_LOBS可以查询到Oracle为列lob创建了两个segments,分别为:SYS_LOB0000014030C00001$$和SYS_IL0000014030C00001$$。
下面介绍几个跟LOB相关的重要存储参数(Storage Parameters)
如果在创建表时没有为LOB对象指定表空间,那么LOG data segment和LOB index segment将会和基表存储在同一个表空间中。
如果为LOB data指定了表空间,那么LOB data和LOB index都将存储被指定的表空间中(这里需要注意,只要为LOB data segment指定了表空间,那么即使为LOB index segment指定表空间也是会被忽略的,即LOB data和LOB index是需要在同一个表空间中。在Oracle较早版本,比如8I及之前时,LOB index和LOB data可以分开存放在不同的表空间中)。
下面介绍几个与LOB相关的参数:
1. IN ROW and OUT OF ROW
在Oracle中,行数据既可以存储在lob column中,也可以不存储在lob column中。不过,该项仅能在建表时指定,后期不可修改。
“STORE AS (enable storage in row)”
若在STORE AS字句中指定了enable storage in row,那么在插入的lob数据小于3964 bytes时,lob data将会被存储于表的数据段中(table segment)。如果插入的lob数据大于3964 bytes,那么lob数据将会被存储于相应的大对象数据段(LOB segment)中,这种情况就跟STORE AS字句中指定为disable storage in row的情况一样了。不过有点特殊的是,若lob data收缩到了小于3694 bytes时,那么其是可以重新存储到table segment中的。另外,有大于3694 bytes的LOB data存于lob segment中,那么依然会有大约36 bytes ~ 84 bytes的数据控制信息(control data)存储在table segment’s row中。
“STORE AS (disable storage in row)”
此选项将不论你存储的lob data是小于3694 bytes还是大于3694 bytes,Oracle都将把lob data存储到lob segment中,当然不是绝对的,仍有20 byte,名为LOB locator以in-line存储于table segment中,该LOB locator用于唯一标识LOB segment中存储的LOB数据。在LOB Locator中有存在一些key,该key是指向一个包含所有blocks(或者是pages)列表的LOB INDEX。Oracle是基于提高检索性能而提供的。
对于out of line LOB,Oracle在分配空间时最小的分配单位为1个数据块(1 database block)。
2. CHUNK size
“STORE AS (CHUNK bytes)”
规范来说,CHUNK要指定为db block size的整数倍大小,但若设置的CHUNK大小为非db block size的整数倍时,那么Oracle会自动将其设置为下一个db block size整数倍。比如,假如数据库的DB_BLOCK_SIZE为8K,而你设置的CHUNK为10000,那么Oracle会自动将其调整为16384,即2*8K
注意:
2.1. CHUNK参数仅在表创建时被设定,后期不可修改
2.2. CHUNK参数对于in-line LOBS是没有效果的(因为其本身就没有使用LOB SEGMENT)。
3. PCTVERSION
“STORE AS ( PCTVERSION n)”
PCTVERSION参数主要是考虑一致性读,用于管理LOB data的前镜像(old copies of LOB data),如果PCTVERSION设置过小,那么很可能会遇到如下错误:
ORA-01555:snapshot too old:rollback segment number with name “” too small
ORA-22924:snapshot too old
设置PCTVERSION可以阻止OLD pages或者OLD copies of LOB data被覆盖,从而强制Oracle分配新的数据块给LOB segment。
该参数的默认是10,通常情况已可满足需求,也可视情况调整;可通过如下命令调整:
SQL> ALTER TABLE tabname MODIFY LOB (lobname) (PCTVERSION n);
4. CACHE
“STORE AS (CACHE)”或者“STORE AS (NOCACHE)”
Oracle的默认值为NOCACHE,这也意味着当服务器进程每次读取LOG data时,都将直接从存储磁盘读取,该操作会产生相应的等待事件(direct path read/direct patch writes)。
如果设置为CACHE,Oracle将会从buffer cache中获取相应的LOB data,产生的等待事件通常是db file sequential read。
有一点需要清楚,普通表(TABLE)的CACHE属性与LOB COLUMN的CACHE属性是不一样的。比如初始化参数CACHE_SIZE_THRESHOLD不会限制读入到buffer cache中的LOB数据大小,这样在大对象访问比较频繁的情况下,极易导致buffer cache被耗尽,从而影响其他正常的数据处理工作。
in-line LOBS是不受CACHE属性影响的,因为in-line LOBs跟普通的表一样是将数据存储在表中,并且通过buffer来读取数据。