Oracle
從表中導出大量文件
我正在使用 Oracle Database 11g 版本 11.1.0.6.0 並且有一個表記錄大量帶有 ID (ID) 的文件 (GIF)。
Name Type ----------------------------------------- ---------------------------- ID VARCHAR2(50) GIF BLOB
目前我正在使用這段程式碼來導出圖片:
DECLARE l_file UTL_FILE.FILE_TYPE; l_name VARCHAR2(50); l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_count INTEGER := 1; l_blob_len INTEGER; BEGIN for x in (SELECT * FROM MY_TABLE) loop l_blob_len := DBMS_LOB.getlength(x.GIF); l_file := UTL_FILE.fopen('BLOBS',x.ID||'-'||l_count||'.gif','wb', 32767); l_pos := 1; WHILE l_pos < l_blob_len LOOP DBMS_LOB.read(x.GIF, l_amount, l_pos, l_buffer); UTL_FILE.put_raw(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; UTL_FILE.fclose(l_file); l_count := l_count + 1; end loop; EXCEPTION WHEN OTHERS THEN IF UTL_FILE.is_open(l_file) THEN UTL_FILE.fclose(l_file); END IF; RAISE; END; /
這段程式碼執行良好,**但問題是,表中有大約 1 億行。**在我的電腦上,導出速度大約只有 7 張圖片/秒。
那麼,有沒有什麼方法可以加速導出呢?謝謝!
您可以使用ORA_HASH函式將表數據拆分為不同的組。查看修改後的 SELECT-FROM-MY_TABLE 子句。在三個不同的 sqlplus 會話中執行此腳本並測量每秒提取的文件數。
腳本 0:
DECLARE l_file UTL_FILE.FILE_TYPE; l_name VARCHAR2(50); l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_count INTEGER := 1; l_blob_len INTEGER; BEGIN for x in (SELECT * FROM MY_TABLE where ora_hash(rowid,2,123)=0) loop l_blob_len := DBMS_LOB.getlength(x.GIF); l_file := UTL_FILE.fopen('BLOBS',x.ID||'-'||l_count||'.gif','wb', 32767); l_pos := 1; WHILE l_pos < l_blob_len LOOP DBMS_LOB.read(x.GIF, l_amount, l_pos, l_buffer); UTL_FILE.put_raw(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; UTL_FILE.fclose(l_file); l_count := l_count + 1; end loop; EXCEPTION WHEN OTHERS THEN IF UTL_FILE.is_open(l_file) THEN UTL_FILE.fclose(l_file); END IF; RAISE; END; /
腳本1:
DECLARE l_file UTL_FILE.FILE_TYPE; l_name VARCHAR2(50); l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_count INTEGER := 1; l_blob_len INTEGER; BEGIN for x in (SELECT * FROM MY_TABLE where ora_hash(rowid,2,123)=1) loop l_blob_len := DBMS_LOB.getlength(x.GIF); l_file := UTL_FILE.fopen('BLOBS',x.ID||'-'||l_count||'.gif','wb', 32767); l_pos := 1; WHILE l_pos < l_blob_len LOOP DBMS_LOB.read(x.GIF, l_amount, l_pos, l_buffer); UTL_FILE.put_raw(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; UTL_FILE.fclose(l_file); l_count := l_count + 1; end loop; EXCEPTION WHEN OTHERS THEN IF UTL_FILE.is_open(l_file) THEN UTL_FILE.fclose(l_file); END IF; RAISE; END; /
腳本 2:
DECLARE l_file UTL_FILE.FILE_TYPE; l_name VARCHAR2(50); l_buffer RAW(32767); l_amount BINARY_INTEGER := 32767; l_pos INTEGER := 1; l_count INTEGER := 1; l_blob_len INTEGER; BEGIN for x in (SELECT * FROM MY_TABLE where ora_hash(rowid,2,123)=2) loop l_blob_len := DBMS_LOB.getlength(x.GIF); l_file := UTL_FILE.fopen('BLOBS',x.ID||'-'||l_count||'.gif','wb', 32767); l_pos := 1; WHILE l_pos < l_blob_len LOOP DBMS_LOB.read(x.GIF, l_amount, l_pos, l_buffer); UTL_FILE.put_raw(l_file, l_buffer, TRUE); l_pos := l_pos + l_amount; END LOOP; UTL_FILE.fclose(l_file); l_count := l_count + 1; end loop; EXCEPTION WHEN OTHERS THEN IF UTL_FILE.is_open(l_file) THEN UTL_FILE.fclose(l_file); END IF; RAISE; END; /
如果這可行,您可以嘗試生成並啟動更多腳本。