1

大量のデータを削除する必要があり、Oracle DB の一時領域が不足しているため、links_data という名前のテーブルから一連のレコードを削除する際に問題に直面しています。

ストアドプロシージャに関する私の知識がほとんどないのと同じように、以下のコードを書きました。しかし、ストアド プロシージャの実行も遅いようです。

シナリオは、links_data テーブルの nm_folder 列が link_folders テーブルとの外部キー関係を持つ、links_data テーブルから行を削除する必要があるということです。link_folders テーブルの nm_folder が主キーで、一度に 10000 レコードを削除してコミットし、もう一度 10000 レコードを削除してコミットするつもりです。

このクエリの最適化を手伝ってください。ありがとうございます。それでは、お元気で、

Declare

Type ty_link_floder is table of number;

tble_id_folder ty_link_floder;

    Cursor c_data is
    select id_folder from link_folders where nm_folder='User Hotlist';

    Begin
    OPEN c_data;

      LOOP
        FETCH c_data
        BULK COLLECT INTO tble_id_folder LIMIT 10000;
        EXIT WHEN tble_id_folder.count = 0;
                    FORALL i IN tble_id_folder.first .. tble_id_folder.last
        DELETE FROM links_data
        WHERE id_folder = tble_id_folder(i);
        COMMIT;

        -- Process contents of collection here.

        DBMS_OUTPUT.put_line(tble_id_folder.count || ' rows deleted from links_data table so far');
        tble_id_folder.delete;
      END LOOP;
      CLOSE c_data;
    Exception
     When others Then
      Commit;
      Raise;
    End;
4

2 に答える 2

4

最初に1つのSQLステートメントで試してみます。

DELETE FROM links_data d
 WHERE id_folder IN (
       SELECT id_folder FROM links_folder WHERE nm_folder='User Hotlist');

一時スペースが不足し、DBAが追加の一時スペースを設定できない場合、最善の方法は、削除する必要のある行なしでテーブルを再作成することです。

CREATE TABLE links_data_tmp AS
SELECT * FROM links_data d
 WHERE id_folder NOT IN (
       SELECT id_folder FROM links_folder WHERE nm_folder='User Hotlist');

その後、でlinks_data_tmp定義されているすべてのインデックスと制約を再構築する必要がありますlinks_data。次に、一時テーブルを実際のテーブルと交換できます。

RENAME links_data TO links_data_old;
RENAME links_data_tmp TO links_data;

すべての特権を再適用することも忘れないでください。

于 2012-12-04T08:43:13.797 に答える
0

links_data(id_folder)table の外部キー列にもインデックスが必要link_foldersです。

ただし、消去するデータの量が非常に多く (たとえば 30% 以上)、削除が継続的なプロセスではない場合は、メンテナンスを行うことをお勧めします -> 必要なデータでテーブルを再作成します。挿入は削除よりも n 倍高速です。

于 2012-12-04T08:37:57.683 に答える