2017-04-22 5 views
0

私は3億のレコードを含むテーブル(テーブルA)を持っています。いくつかの基準に基づいてデータ保持アクティビティを実行したいと思います。だから私はテーブルの約200Mのレコードを削除したい。条件に基づいて非常に大きなテーブルから古いレコードを削除する

パフォーマンスに関して、私はテーブル-Aからの最も古い10Mレコードで新しいテーブル(テーブル-B)を作成することを計画しました。テーブルAから10Mのレコードを抽出し、SQLローダーを使用してテーブルBにロードすると約5時間かかります。

私は既にインデックスを作成しており、適用可能な場合は常にパラレル32を使用しています。

私が知りたいと思ったことは、

  • 表-Aから抽出するために、表-Bにそれをロードするために任意のより良い方法はあります。
  • 一時テーブル(表B)を作成する以外の方法がありますか?

DBMS:Oracle 10g、PL/SQL、およびShell。

ありがとうございました。

+3

両方のテーブルが同じデータベースにありますか?はいの場合、ホエーはSQL Loaderを使用してロードしていますか?単純に 'tableB select * from tableA'に挿入できませんか?また、より速い挿入のために 'no logging'としてtableBを作成してください。これについての詳細は、Googleの「nologging」を参照してください。 – Utsav

+0

私は@Utsavに同意します。ちょうど 'insert/* + append */t2 select * from t1 select *何時でも何時にも数分かかるはずです。私が心配しているのは「削除」です。あなたはこれを行う必要がある次回のためにパーティショニングするオプションがありますか? –

+0

「テンポラリテーブル(テーブルB)の作成以外にも優れたアプローチはありますか?」に関しては、私はあなたのプロセスロジックを理解していません。テーブルBとは何ですか?つまり、それを作成する代わりに、それを作成しないことです。 –

答えて

1

表のパーティションになります新しいテーブルの名前を古いテーブルの名前に変更します。新しいテーブルを作成する1つの可能性は、テーブル作成時の文(CTAS)を作成することですが、実行中のシステムへの影響をより小さくする可能性もあります。マテリアライズド・ビューを使用して残りのデータを選択し、マテリアライズド・ビューを表に変換できます。このアプローチの詳細は要件に依存します。 この読み書きは、古いテーブルの行を削除する方がはるかに効率的です。

古いテーブルの行を削除する場合は、古いテーブルを再編成する必要があります。残りの30%のデータを書き込むことになります。

-1

おそらくより良いアプローチは、表Aのパーティションになりますが、ない場合には、迅速かつ簡単に試すことができます。

declare 
    i pls_integer :=0 ; 
begin 
    for r in 
    ( -- select what you want to move to second table 
     SELECT 
      rowid as rid, 
      col1, 
      col2, 
      col3 
     FROM 
      table_a t 
     WHERE 
      t.col < SYSDATE - 30 --- or other criteria 
    ) 
    loop 
     insert /*+ append */ into table_b values (r.col1, r.col2, r.col3); -- insert it to second table 
     delete from table_a where rowid = r.rid; -- and delete it 
     if i < 500 -- check your best commit interval 
     then 
      i:=i+1; 
     else 
      commit; 
      i:=0; 
     end if;  
    end loop; 
    commit; 
end; 

上記の例では、あなたが小さな500行の取引であなたのレコードを移動します。コレクションと一括挿入を使用して最適化できますが、シンプルなコードを保持したいと考えていました。その後、テーブルに切り捨てる(ここでa =基準テーブルBから選択*)

+0

-1これは良いアドバイスではありません。それは負荷の持続時間を5時間からさらに長い時間に吹き飛ばします。既に述べたように、拳はテーブルBを使うことが本当に必要かどうかを考えています。必要な場合は2番目に 'insert append'とnologgingを使います。メソッドはこれを考慮に入れませんが、データを削除する時間が長くなります。 append-hintはinsert-values文には何の影響もなく、pl/sqlとSQL文脈を絶えず切り替えることで、このアプローチはさらに遅くなります。 – miracle173

+0

これは 'insert * values'ステートメントの'/* + append_values */'です。これは11.2で追加されただけで、OPはまだ10gです。そして、そのループには「コミット」があるようです。 –

0

使用するのが最善のROWID使用しますが、インラインカーソルは、値がテーブルに挿入Uに より多くのを助けることができる

0
  • 抽出するための任意のより良い方法はありますテーブル-Aからそれをロードするには?パラレルCTAS - create table-bをtable-aから選択して使用することができます。一段階で圧縮と並列クエリを使用できます。

  • 表B。 temp
    テーブル(テーブルB)を作成する以外の方法はありますか?より良いアプローチは、あなたのテーブルのレコードの70%を削除したい場合は、最良の方法は、ドロップ、行の残りの30%を含む新しいテーブルを作成することです

0

条件に基づいてテーブルを分割することはオプションです。

基準が月の場合を考えてみましょう。すべての1月のデータはJanパーティションに分類されます。すべての2月のデータは2月のパーティションに分類されます...

その後、古い1月のデータをすべて削除するときは、パーティションをドロップするだけです。

関連する問題