2

厄介な問題があります。Oracle 10 には、そのようなことが何度も繰り返されるビューとテーブルのペアがあります。

proc_log('DELETE 1');
DELETE FROM table_1;
proc_log('INSERT 1');
INSERT INTO table_1 SELECT * FROM view_1;
proc_log('FINISH 1');

View/Table 2 と 3 と 4 と 5... と 36 も同じです。

私はこのようなことをしたいと思います:

PROCEDURE proc_import(p_table VARCHAR2) IS
BEGIN
    proc_log('DELETE ' || p_table);
    EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table;
    proc_log('INSERT ' || p_table);
    EXECUTE IMMEDIATE 'INSERT INTO table_' || p_table || ' SELECT * FROM view_' || p_table;
    proc_log('FINISH || p_table);
    COMMIT;
END;

次に、36 ペアすべてに対して関数を呼び出します。

驚くべきことではありませんが、これはハードコードされたものよりも約 50% 遅くなります。

私の質問: 高速化する方法について誰か考えがありますか? またはさらに良いことに、どうすればこれを他とは違うものにすることができますか?


編集

全体は次のように構築されます。

CREATE OR REPLACE PACKAGE PKG_IMPORT IS
  PROCEDURE proc_log IS BEGIN [funky not important stuff] END;
      
  PROCEDURE proc_import IS
  BEGIN
      proc_import_table('1', TRUE);
      proc_import_table('2');
      proc_import_table('3');
      proc_import_table('4', TRUE);
      proc_import_table('5');
      ...
      proc_import_table('36');
  END;

  PROCEDURE proc_import(p_table VARCHAR2, p_whole BOOLEAN DEFAULT FALSE) IS
  BEGIN
    proc_log('DELETE ' || p_table);
    IF p_whole THEN
      EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table;
    ELSE
      EXECUTE IMMEDIATE 'DELETE FROM table_' || p_table || ' WHERE business_logic_applies';
    END IF;
    proc_log('INSERT ' || p_table);
    EXECUTE IMMEDIATE 'INSERT INTO table_' || p_table || ' SELECT * FROM view_' || p_table;
    proc_log('FINISH || p_table);
    COMMIT;
  END;
 END PKG_IMPORT;

プロシージャ proc_import は、ジョブによって 1 晩に 1 回呼び出されます。すべての proc_import_table 呼び出しがハードコーディングされている理由は、一部のテーブルで追加のインポート情報が必要になるためです。

許可されているかどうかわからないため、ここに元のコードをコピーして貼り付けることはできません。お役に立てれば...

4

2 に答える 2

2

まず、削除する行に関する条件がない場合は、テーブルを切り捨てることができます。

TRUNCATE TABLE table_1;

TRUNCATEこれは ddl 操作であり、行を物理的に削除するのではなく、最高水準点のみを操作するため、操作が非常に高速になります。ただし、これは DDL であるため、ロールバックできないことに注意してください。

一方、通常の挿入ではなく、ダイレクト パス挿入を実行できます。これを試して:

INSERT /*+ append */ into table_1 select * from view_1;

これにより、Oracle はハイ ウォーターマークのすぐ上にデータを書き込み、操作を高速化します。テーブルPARALLEL. _

于 2012-11-08T14:38:40.607 に答える
0

オラクルはクエリをプリコンパイルできるため、元のコードはより速く実行されますが、「すぐに実行」では実行できません。

新しいコードはより簡潔に見えるかもしれませんが、実際にははるかに読みにくくなっています。少なくとも、テーブル番号を渡すのではなく、完全なテーブル名を指定する必要があります。そうしないと、コードを見ている他の人が番号の意味を理解する必要があります。

そうは言っても、私は 36 の delete ステートメントと 36 の insert ステートメントを見たいと思います。より短いプロシージャに役立つ場合は、これらのステートメントをすべて独自のプロシージャに配置できます。

于 2012-11-08T11:47:29.327 に答える