批量数据文件输出PL / SQL

时间:2014-03-20 09:09:34

标签: performance plsql oracle11g

在我的PL / SQL函数中,我将输出一个1400万行的csv文件。每行将有3个字段。

我担心I / O进程运行时间。我可以为这个批处理创建和输出多个csv文件。我不想逐行输出。

写文件的最佳和快捷方式是什么。例如,获取数据然后填入记录。然后写下文件。

感谢。

1 个答案:

答案 0 :(得分:0)

从Oracle 10g开始,可以使用DBMS_XSLPROCESSOR.CLOB2FILE过程将CLOB写入一个文件,只需一次调用。在下面的示例中,我们将使用我们的数据准备临时CLOB,而不是使用UTL_FILE编写它。当所有源数据都添加到CLOB后,我们将在一次调用中将其写入平面文件。

SQL> DECLARE
  2
  3     v_file    CLOB;
  4     v_buffer  VARCHAR2(32767);
  5     v_name    VARCHAR2(128) := 'clob2file_buffered.txt';
  6     v_lines   PLS_INTEGER := 0;
  7     v_eol     VARCHAR2(2);
  8     v_eollen  PLS_INTEGER;
  9     c_maxline CONSTANT PLS_INTEGER := 32767;
 10
 11  BEGIN
 12
 13     v_eol := CASE
 14                 WHEN DBMS_UTILITY.PORT_STRING LIKE 'IBMPC%'
 15                 THEN CHR(13)||CHR(10)
 16                 ELSE CHR(10)
 17              END;
 18     v_eollen := LENGTH(v_eol);
 19
 20     DBMS_LOB.CREATETEMPORARY(v_file, TRUE);
 21
 22     FOR r IN (SELECT x || ',' || y || ',' || z AS csv
 23               FROM   source_data)
 24     LOOP
 25
 26        IF LENGTH(v_buffer) + v_eollen + LENGTH(r.csv) <= c_maxline THEN
 27           v_buffer := v_buffer || v_eol || r.csv;
 28        ELSE
 29           IF v_buffer IS NOT NULL THEN
 30              DBMS_LOB.WRITEAPPEND(
 31                 v_file, LENGTH(v_buffer) + v_eollen, v_buffer || v_eol
 32                 );
 33           END IF;
 34           v_buffer := r.csv;
 35        END IF;
 36
 37        v_lines := v_lines + 1;
 38
 39     END LOOP;
 40
 41     IF LENGTH(v_buffer) > 0 THEN
 42        DBMS_LOB.WRITEAPPEND(
 43           v_file, LENGTH(v_buffer) + v_eollen, v_buffer || v_eol
 44           );
 45     END IF;
 46
 47     DBMS_XSLPROCESSOR.CLOB2FILE(v_file, 'DUMP_DIR', v_name);
 48     DBMS_LOB.FREETEMPORARY(v_file);
 49
 50     DBMS_OUTPUT.PUT_LINE('File='||v_name||'; Lines='||v_lines);
 51
 52  END;
 53  /

文件= clob2file_buffered.txt;行= 1000000

PL / SQL程序已成功完成。

经过时间:00:00:28.65

CLOB特定的代码在上面突出显示并且不言自明(可能除了第13-17行的行尾字符分配外,对于Windows来说是不同的.UTL_FILE管理端口特定的结尾 - 为我们提供线路转换,但对于CLOB,我们必须自己管理。)

特别感兴趣的是第47行的DBMS_XSLPROCESSOR调用,它是我们对目标平面文件的唯一写操作。我们总体上可以看到这种技术在性能上与我们的缓冲UTL_FILE机制相似(CLOB方法稍微快一些)。因此,我们有另一种写入数据的方法,但是使用CLOB会产生额外的成本(例如,临时表空间和缓冲区缓存)。如果要转储的数据量很大,则此方法可能会对我们的临时表空间施加太大压力,并导致其他用户出现问题(大型排序操作,散列连接,全局临时表等)。

使用此方法时应小心。