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。

 

posted @ 2020-12-30 11:12  闻歌感旧  阅读(1354)  评论(0编辑  收藏  举报