如何提高PHP OCI-Lob :: save的性能

时间:2014-07-31 16:39:27

标签: php oracle blob oci

我有一个脚本可以导入大量文本文件,处理它们然后将数据保存到Oracle数据库。它还将原始数据文件的副本保存到BLOB列中。导入72个文件时,每个文件中包含大约40,000行数据(每个大约3.5Mb),脚本执行时间超过一分钟。

使用xdebug对脚本进行概要分析后,看来对OCI-Lob :: save的调用占用的时间最多(~90%)。这是我用来保存BLOB的PHP代码 - 我认为非常标准:

$this->_db->setSQL('INSERT INTO IMPORTED_FILES (FILE_BLOB, FILE_NAME, LAST_MODIFIED_DATE, IMPORTED_BY, IMPORTED_DATE) VALUES
                        (EMPTY_BLOB(), :fileName, :lastMod, :userId, SYSDATE) RETURNING FILE_BLOB INTO :fileBlob');
    $blob = \oci_new_descriptor($this->_db->con);
    $this->_db->bind(":fileBlob",$blob,-1,OCI_B_BLOB);
    $this->_db->bind(':fileName',$this->_name);
    $this->_db->bind(':lastMod',$this->_lastModifiedDate);
    $this->_db->bind(':userId',$_SESSION['userid']);
    $this->_db->execute(false);
    $blob->save($this->_contents);

表格定义:

CREATE TABLE IMPORTED_FILES
  (
    "FILE_ID" NUMBER(*,0) NOT NULL ENABLE,
    "FILE_BLOB" BLOB NOT NULL ENABLE,
    "FILE_NAME"          VARCHAR2(255 CHAR) NOT NULL ENABLE,
    "LAST_MODIFIED_DATE" VARCHAR2(255 CHAR) NOT NULL ENABLE,
    "IMPORTED_BY"        VARCHAR2(255 CHAR) NOT NULL ENABLE,
    "IMPORTED_DATE" DATE NOT NULL ENABLE,
    "REPORT" CLOB,
    CONSTRAINT "IMPORTED_FILES_PK" PRIMARY KEY ("FILE_ID") USING INDEX
    TABLESPACE "DATA_INDEX" ENABLE
  )

有没有办法更快地保存BLOB?

更新

不确定这是否有帮助,但我在SQL Developer中找到了以下窗口,其中显示了一些有关BLOB字段的参数。可以更改任何这些设置以提高效率吗?

enter image description here

1 个答案:

答案 0 :(得分:1)

(这是一个扩展的评论而非答案。)

第一步,通常是最困难的一步,就是找到什么是慢的。以下代码仅在数据库中运行,并将告诉您写入数据的最佳情况。

drop table test1;
create table test1(a clob);

--Time to write 72 3.5MB CLOBs.
--On my old desktop this runs in about 15 seconds.
declare
    v_clob clob := 'A';
begin
    --Create a 3.5MB LOB.
    for i in 1 .. 350 loop
        dbms_lob.append(v_clob, lpad('a',10000, 'a'));
    end loop;

    for i in 1 .. 72 loop
        insert into test1 values (v_clob);
    end loop;
    commit;
end;
/

如果该代码在不到一分钟的时间内运行,那么数据库可能不是问题 - 更仔细地查看PHP或查看网络。如果该代码在不到一分钟的时间内运行,请进一步向下钻取并找到该语句正在等待的内容。像这样的查询可能是一个好的开始:

select event, v$active_session_history.*
from v$active_Session_history
where sql_id = 'ghwdpz6v9k2cj'
order by sample_time desc;