件数は300万件。データの中身を一部確認してみると、SELECT * FROM T_CUSTOMERWHERE C_ID <= 30ORDER BY C_ID; C_ID列は、シーケンシャルに番号が増えていってます。このテーブルが占めているサイズを確認すると、. お世話になります。Oracle 9iで特定のテーブルを高速に削除したいのですがTruncateを使うと、Insertが完了し、Commitするまでの間に読み取り一貫性が崩れるので、使いたくありません。(他のセッションからは、当該テーブルは0件と映るの このテーブルから、200万件のデータを削除してみます。DELETE FROM T_CUSTOMERWHERE C_ID <= 2000000; 確認したところ、サイズは全く変化がないことが確認できました。この理由は、DELETE文では、ORACLEのハイウォーターマーク(HWM)に変化はなく、一度確保した領域は解放されないためです。ハイウォーターマーク(HWM)とは、テーブルなどに割り当てたブロックの中で、今までデータが挿入されたことがある最後尾のブロックのことで、その位置が変わらないと領域は解放されません。, このハイウォーターマーク(HWM)を低下させる方法としては、以下のような方法があります。1.TRUNCATE でデータを削除する。  ただし、データを全件削除することになります。  (※最初に CREATE TABLE AS SELECT で元のテーブルを別テ   ーブルにコピーしておけば、TRUNCATE後にデータを流し   込むことはできます)2.Export/Importでデータを復元する。  Exportした後に、一度テーブルをDROPして削除してから  Importします。3.ALTER TABLE MOVE でテーブルを新しいセグメントに移動し  て再作成する。4.ALTER TABLE SHRINK SPACE による断片化の解消。, それでは、1.のTRUNCATE文でデータを削除してみます。その前に、データを戻せるように別テーブルにコピーします。. ALTER TABLE T_CUSTOMER ENABLE ROW MOVEMENT; ALTER TABLE T_CUSTOMER SHRINK SPACE CASCADE;ALTER TABLE T_CUSTOMER DISABLE ROW MOVEMENT; 2番目のSHRINK SPACE CASCADE の処理に多少時間がかかりました。ここで、テーブルのサイズを確認してみます。, T_CUSTOMERのテーブルのサイズは、21.625MB、インデックスも16MBとなり、領域が解放されたことが確認できました。なお、レコード数が少ない場合においては、ハイウォーターマークが思ったより低下しない場合もあり、これは、行移行や行連鎖の状態によって効果は異なるようです。連鎖状態を解消してからであれば、効果は高いということです。, 古いブログ記事にコメント申し訳ありません。 つづいて、このテーブルにテストデータを100万件登録します。男女比は半々になるように、行番号の偶数奇数で男女を分けます。, パーティションテーブルを導入できれば削除処理を高速化することができます。 EXTENT_MANAGEMENT が LOCAL、SEGMENT_SPACE_MANAGEMENT が AUTO になって この記事では、パーティション表を使った高速なデータ削除の方法を紹介します。, パーティション化された表(テーブル)のことです。大きな表やインデックスを、パーティションというより小さくて管理しやすい部分に分割します。パーティション化を行うと、大きなデータベースに対する管理を簡素化できます。, パーティション化とは、大規模な表や索引を、パーティションというより小さくて管理しやすい部分に分割して、この種の表や索引をサポートするときの主な問題に対処します。パーティション表にアクセスする際、SQL問合せとDML文を変更する必要はありません。ただしパーティションを定義すると、DDL文は表や索引全体ではなく、個々のパーティションへのアクセスやその操作ができるようになります。パーティション化を行うと、このようにしてラージ・データベース・オブジェクトの管理を簡素化できます。また、パーティション化は、アプリケーションに対して完全に透過的です。 テーブルの設計時にパーティションテーブルを使えるか、削除パフォーマンス等を含め、考慮に入れておきたいですね。, replicationさんは、はてなブログを使っています。あなたもはてなブログをはじめてみませんか?, Powered by Hatena Blog deleteと領域の解放(oracle) oracleを使用している場合に、使用している表領域のサイズがかなり大きくなってしまったので、データを削除して使用できる領域を増やそうと考える場合があると思います。 OracleのDelete処理は時間がかかります。そのため、大量のレコードを削除する際はあれこれ工夫が必要です。 INSERT文をパラレル実行することで、実行速度を速くする方法です。 これは1本のSQLを複数のORACLEプロセスによって分散して実行する方法です。 範囲で分割するレンジ・パーティションや指定した値で分割するリストパーティションなど、パーティションの種類は以下のページにわかりやすくまとめられています。, はじめに、パーティション表を用意します。今回はリスト・パーティションを作成します。, このテーブルは性別カラムを持ち、男性はパーティション1(part1)、女性はパーティション2(part2)というようにパーティションを分割します。 Oracle SQLチューニング講座(12):更新/挿入/削除のSQLを高速化する3つの技とは?(2/3) [倉田寛正,株式会社アゲハ] いることを確認してみてください。そうでなければ変更する必要があります。, 次のHTML タグと属性が使えます:
. Oracle初心者なのですが、とてもためになりました。 ダイレクト・ロードを大幅に高速化する1つの方法は、redoログの使用を 最小限に抑えることです。 それには3通りの方法があります。アーカイブを使用禁止にする方法、ロードをリカバリ不可能に指定する方法、ロードされるオブジェクトに対してsqlのnologgingパラメータを設定する方法です。この項では、すべての方法を説明します。 deleteにてwhere句の条件で数百万件のレコードを削除したいのですが、効率的な方法を教えてください。sql初心者です。logの肥大化や削除に非常に時間がかかるのを心配してます。こんにちは。以下のように分割して削除する方法如何でしょ プライマリ・コンテンツに移動. この後、コピーしたデータを戻してCOMMITし、コピーした不要なテーブルを削除します。INSERT INTO T_CUSTOMER SELECT * FROM COPY_T_CUSTOMER;COMMIT;DROP TABLE COPY_T_CUSTOMER; 確かに、T_CUSTOMERのテーブルのサイズは、22MB、インデックスも30MBとなりました。, 再度、データを300万件作成します。これは、以前、バルク処理の題材のときの方法で作成します。, expdp blog_test/パスワード directory=DP_DIR tables=t_customer dumpfile=t_customer.dmp(※処理を行う前にディレクトリの作成とディレクトリへのread/write権限の付与が必要), impdp blog_test/パスワード directory=DP_DIR dumpfile=t_customer.dmp, T_CUSTOMERのテーブルのサイズは、22MB、インデックスも18MBとなり、領域が解放されたことが確認できました。, 次に、3.のテーブルを新しいセグメントに複製し、既存のものを削除するという方法(テーブルの移動)による再作成を行ってみます。, まずは、再度300万件のデータに戻し、その後、200万件のデータを削除します。(動作については省略)このときのテーブル・インデックスのサイズは、テーブルが64MB、インデックスが47MB。, テーブルのサイズは、テーブルが64MBから22MBに小さくなっていることが確認できました。※LONG / LONG RAW のある表は、この方法での移動はできないとのこと。, 最後に、4.のALTER TABLE SHRINK SPACE による断片化の解消を試してみたいと思います。こちらもまずは、再度300万件のデータに戻し、その後、200万件のデータを削除します。(動作については省略)このときのテーブル・インデックスのサイズは、テーブルが64MB、インデックスが47MB。, 断片化の解消をしたいテーブル「T_CUSTOMER」に対して、以下のSQLを順に実行します。.