Oracle提升读取Lob数据性能的几种有效方法
一、问题
在Oracle中,读取Lob(BLOB或CLOB)的性能一直很差。根据个人经验,读取Lob用时大致是读取常规字段的几十到一百倍。
为提升读取LOB数据的性能,根据搜素到的资料,做过许多种尝试。其中,效果比较明显的方法如下:
- 为Lob设置独立表空间,用时再读取;
- 将Lob的存储格式改为SecureFile;
- 使用DBMS_LOB包替代。
而其余的方法,比如并行(parallel)、cache read等,在本项目测试中效果不明显。
二、LOB独立表空间
LOB字段与常规字段分离,分别存储在不同的表空间。同时,只有在需要时再读取LOB字段。
这点容易理解,也是长久以来一直遵循的原则,不再赘述。
三、使用SecureFile存储格式
从11g开始,Oracle提出了SecureFile的概念,与原来的BasicFile相比,SecureFile提供了LOB智能压缩、取消重复、透明加密等功能。
- 首先初始化参数不能设置为NEVER和IGNORE(缺省值是PERMITTED)。
- 建表时,指定LOB存储格式为SecureFile:LOB(lob_data) AS SecureFile;
-
create table my_table ( id number(10) not null primary key, lob_data blob ) LOB(lob_data) STORE AS SECUREFILE (TABLESPACE TS_LOB DISABLE STORAGE IN ROW);
- 对已存在的表,也可更改Lob存储格式,但此时会在全表加锁,慎用。
本项目的测试结果表明,将LOB存储格式修改为SecureFile,相应参数均取默认值,读取用时大约能缩短30%~50%。
四、使用DBMS_LOB包的功能
讲真,在做此项测试之前,本来是没抱什么希望。
首先,在数据库里创建一个函数,目的仅仅是使用dbms_lob的功能而已:
create or replace function proc_getblob(p_Blob in BLOB) return BLOB IS v_dest_blob BLOB; begin dbms_lob.createtemporary(v_dest_blob, TRUE); dbms_lob.append(v_dest_blob, p_blob); return v_dest_blob; end; /
然后,将读取记录的sql修改为:
-- 原sql: select id, lob_data from my_table where ...; select id, proc_getblob(lob_data) from my_table where ...;
意想不到的是,总体用时竟降低了30%左右。
五、总结
根据本次的测试结果,使用SecureFile和DBMS_LOB包在提升读取LOB性能方面确有比较明显的结果。
即使将上述措施均予以应用,读取LOB数据的用时仍是常规数据的十倍以上。因此,若非确有必要,还是尽量避免使用LOB。
声明:内容可以转载,但须标明出处(http://www.cnblogs.com/wggj),请尊重作者(闻歌感旧)的劳动,谢谢!