我有一个脚本可以导入大量文本文件,处理它们然后将数据保存到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字段的参数。可以更改任何这些设置以提高效率吗?
答案 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;