我有一个脚本可以导入大量文本文件,处理它们,然后将数据保存到 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 字段的参数。是否可以更改这些设置中的任何一个以提高效率?
最佳答案
(这更像是一个扩展评论,而不是一个答案。)
第一步,通常也是最困难的一步,就是找出到底是什么慢了。下面的代码仅在数据库中运行,并将告诉您写入数据的最佳情况。
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;
关于php - 如何提高 PHP OCI-Lob::save 的性能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25064484/