2

私は sql plus を使用してクエリ (選択) を実行し、スプール オプションを使用して結果をファイルにダンプしています。約 1400 万の行があり、ダンプを実行するのに約 12 分かかります。ダンプを高速化する何かがあるかどうか疑問に思っていましたか?

ここに私のSQLとオプションの下に:

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 行でわずかに高速でしたが、1,400 万行でそれを吹き飛ばすと、それだけの価値があるかもしれません。

これよりも速くなりたい場合は、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

それで、これはネットワーク上で行われますか、それともデータベースのあるボックスにログインしていますか? アクセスできる場合は、データベースが存在するボックスで sqlplus セッションを実行し、ファイルを圧縮してからローカル マシンにファイルを送信できます。何百万もの小さなレコードを送信するよりも、大きなファイルをネットワーク経由で送信する方が速い場合があります。もちろん、これで超高速になるわけではありませんが、時間が短縮される可能性があります。

また、それほど多くのデータをファイルにスプールする必要がありますか? 代わりにエクスポートできますか?

于 2010-04-01T14:25:41.370 に答える
1

典型的なクエリでは、14Mレコードは少なくとも数百メガバイトのデータであり、サーバーから取得し、接続を介して渡し、ディスクに保存します。

これを考えると、12分は私にはあまり聞こえません。

ただし、クエリを最適化できる可能性は依然としてあります。ここに投稿していただけますか?

于 2010-04-01T12:53:23.473 に答える
0

スクリプトを追加することで、出力バッファリングを有効にできます

SET FLUSH OFF

ただし、結果はOSによって異なります。

于 2010-04-01T21:06:40.757 に答える
0

SQL*Plus でクエリから多くの結果を取得する場合、データの実際の表示に時間がかかることがわかりました。データをファイルにスプールしている場合は、それが可能SET TERMOUT OFFであり、画面への書き込みに時間を費やす必要がないため、クエリははるかに高速に実行されます。

于 2010-04-03T15:44:04.500 に答える
0

いくつかのオプションは、本当の第一人者であるTom Kyteから入手できます。

于 2010-04-09T16:40:53.670 に答える