【问题标题】:Bulk data file output PL/SQL批量数据文件输出PL/SQL
【发布时间】:2014-04-27 00:20:24
【问题描述】:

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

恐怕I/O进程运行时间。我可以为这批创建和输出多个 csv 文件。我不想使用逐行输出。

什么是写文件的最佳和快速的方法。例如,获取数据然后填充到记录中。然后写入文件。

谢谢。

【问题讨论】:

标签: performance plsql oracle11g


【解决方案1】:

从 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 管理特定于端口的 end-of -line 转换,但对于 CLOB,我们必须自己管理)。

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

因此在使用此方法时应小心。

【讨论】:

    猜你喜欢
    • 2016-07-09
    • 2011-07-17
    • 2018-07-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-16
    • 1970-01-01
    相关资源
    最近更新 更多