2

我正在使用 sql plus 执行查询(选择)并将结果转储到文件中,使用假脱机选项。我有大约 1400 万行,转储大约需要 12 分钟。我想知道是否有什么东西可以让转储更快?

下面是我的 sql plus 选项:

whenever sqlerror exit sql.sqlcode
        set pagesize 0
        set linesize 410
        SET trimspool ON
        set heading on
        set feedback off
        set echo off
        set termout off
        spool file_to_dump_into.txt 
        select * from mytable;

谢谢。

4

7 回答 7

7

您是在连接和分隔列,还是在导出固定宽度?

请参阅有关SQL*Plus 脚本调优的文档。具体到您的脚本,这里有一些可能的方法来加快它:

  1. 确保 LINESIZE 尽可能小。添加您的最大列长度(如果不是固定宽度,则加上分隔符)。这会对性能产生显着影响,因为 SQL*Plus 会为每个导出的行分配该数量的内存。410不是那么大,但如果你能减少它会有所帮助。根据我的经验,这产生了很大的不同。
  2. 不要打开TRIMSPOOL。这也会产生很大的影响。然后,每一行都将被填充到 LINESIZE,但具有最佳线大小,并且取决于您使用文件的方式,这可能是可以接受的。但是,如果您想完全消除尾随空格,则在导出后使用其他方法修剪它们通常会更快。
  3. 使用 ARRAYSIZE。它可能会有所帮助(一点点)。它设置 SQL*Plus 的提取大小。默认为 15 行。例如,达到 100 可能会有所帮助,但太大可能会降低速度。

希望这可以帮助!

于 2010-04-06T23:29:52.117 回答
2

您可能会发现使用 UTL_FILE 更快,但可能不会快得多。

在我的测试中,它在大约 20k 行上略快,尽管超过 1400 万行,但它可能是值得的。

我相信,如果您想比这更快,那么要走的路是 pro*c .. 但我还没有深入了解,所以不能真正提供建议。

set pagesize 1000
set FLUSH OFF
drop user usera cascade;
create user usera default tablespace users identified by abc123;
grant create session to usera;
grant resource to usera;

create or replace directory testdir as '/tmp';
grant read,write on directory testdir to usera;
grant execute on UTL_FILE to usera;

connect usera/abc123;

set timing on

spool /tmp/spooltest.txt
select object_name from all_objects;
spool off

DECLARE
 v_file UTL_FILE.FILE_TYPE;
 TYPE t_col is table of all_objects.object_name%type index by PLS_INTEGER;
 v_object_names t_col;

BEGIN
  v_file := UTL_FILE.FOPEN('TESTDIR','utlfiletext.txt','w');

  select object_name BULK COLLECT INTO v_object_names
  from all_objects;

  for idx IN 1 .. v_object_names.COUNT LOOP
    UTL_FILE.PUT_LINE(v_file, v_object_names(idx), FALSE);
  END LOOP;

   UTL_FILE.FCLOSE(v_file);
END;
/

结果。顶部结果仅来自 sqlplus,底部使用 UTL_FILE

23931 rows selected.

Elapsed: 00:00:06.60

PL/SQL procedure successfully completed.

Elapsed: 00:00:05.45
于 2010-04-02T01:44:43.003 回答
1

对于典型的查询,14M记录至少是几百兆字节的数据,要从服务器中取出,通过连接传递并保存到磁盘。

鉴于此,12分钟对我来说听起来并不多。

但是,您的查询仍然可以优化。你能把它贴在这里吗?

于 2010-04-01T12:53:23.473 回答
1

那么这是通过网络还是您登录到具有数据库的框?如果您有访问权限,也许您可​​以在数据库所在的机器上运行 sqlplus 会话并将文件压缩,然后将文件发送到本地计算机。通过网络发送大文件可能比发送数百万条小记录更快。当然,这不会让它变得超级快,但可能会节省一些时间。

还有这么多数据,您真的需要将其假脱机到文件中吗?你可以做一个出口吗?

于 2010-04-01T14:25:41.370 回答
0

从 SQL*Plus 中的查询获得大量结果时,我发现需要花费大量时间的一件事是数据的实际显示。如果您将数据假脱机到文件中,则可以SET TERMOUT OFF,并且查询运行得更快,因为它不必花时间将其写入屏幕。

于 2010-04-03T15:44:04.500 回答
0

您可以通过添加到脚本来启用输出缓冲

SET FLUSH OFF

但结果取决于您的操作系统。

于 2010-04-01T21:06:40.757 回答
0

Tom Kyte提供了一些选项,他是一位真正的大师。

于 2010-04-09T16:40:53.670 回答