• ベストアンサー

Truncate以外で高速にテーブル内全件削除する方法

お世話になります。 Oracle 9iで特定のテーブルを高速に削除したいのですが Truncateを使うと、Insertが完了し、Commitするまでの間に 読み取り一貫性が崩れるので、使いたくありません。 (他のセッションからは、当該テーブルは0件と映るのではなく 削除前の状態が見えてほしい。) なにか逃げ道ありませんでしょうか?

  • Oracle
  • 回答数3
  • ありがとう数5

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

>Truncateされた後、かつ次のCommitまでの間に >他に新たにセッションが確立された場合に、この状況となります。 DDLに分類されるTRUNCATEは、非トランザクションなSQLですので、 コミットするまでもなく、自動的に即時反映です。 占有的に動作し、即時反映するので、読みとり一貫性が崩れることは ありません。 トランザクション中で削除するには、DELETE文を実行する以外に 削除の方法はありません。 データベース環境を変更できるのであれば、ログの抑制等で、 DELETE文速くすることは出来ますが。

kurinkurinkurin
質問者

補足

>> データベース環境を変更できるのであれば、ログの抑制等で、 >> DELETE文速くすることは出来ますが。 はい、こういう逃げ道を探しています。 これについて、詳しく教えていただませんでしょうか?

その他の回答 (2)

回答No.3

ALTER TABLE テーブル名 NOLOGGING; や ALTER INDEX インデックス名 NOLOGGING; をすれば、REDOログの出力が減り、相応の時間が節約できます。 当然、REDOログを出力しないことによる弊害も考慮してください。 詳しくはマニュアルで。

kurinkurinkurin
質問者

お礼

k_o_r_o_c_h_a_n さん ありがとうございます。 NOLOGGINGオプションをつけてやってみたいと思います。 ありがとうございました。

回答No.1

>他のセッションからは、当該テーブルは0件と映るのではなく >削除前の状態が見えてほしい。 このような状況にはならないと思いますよ。 他セッションで使われているテーブルは、Truncateが拒否されるハズです。 Tuncateできるなら、瞬間的には占有状態のハズですから・・

kurinkurinkurin
質問者

補足

Truncateされた後、かつ次のCommitまでの間に 他に新たにセッションが確立された場合に、この状況となります。

関連するQ&A

  • 大量レコードをTRUNCATEせずにすばやく削除する方法

    大量レコードをTRUNCATEせずにすばやく削除する方法 100万レコードあるテーブルのうち1万レコードを残して削除したい。TRUNCATEではWHERE句が指定できないので不可。DELETEでは遅すぎる。何かいい方法はないでしょうか? 1万レコードを一時テーブルに退避してTRUNCATE後に1万レコードをINSERTというのは無しです。1万レコードが1秒でもテーブル上から消えてはいけません。 Oracle10g

  • TruncateしたテーブルへのInsertの遅さが気になる

    こんにちわ。 日次処理として、毎晩ワークテーブルをTruncateしてInsertしなおすというプログラムを数年前に作りました。 このプログラムはVB6、ADO、OLE DBプロバイダはOracleのものを使っています。 他のテーブルからSelectし、それを元に1レコードずつInsert文を作っては実行を繰り返す処理で正直遅いのですが、このプログラムの動作が不思議です。 日々数十万件のInsertを行っているのですが、ログを確認すると最初の2万件のInsertには40分掛かるわりに最後の2万件は5分で終わるのです。 今まで処理時間の遅さが問題になることもなく、バグもなく動いているしであまり気にしていなかったのですが、最近なぜこのような動きになるのか気になってきました。 最初も最後もSelect結果に偏りはなく、Insert文を作る処理に掛かっている時間は同じようなものかと思います。 とすると、遅いのはDBでのInsert処理か?と考えています。 レコード件数が少ないうちのInsertには時間が掛かるものなんでしょうか? だとするとそれはなぜ? 別に処理速度を速くしたいとか言うことではなく、なぜInsertの処理時間にこれほどの差が生じるのかが気になっています。 なおこのテーブルは主キー以外に索引を作っていません。 Insert文を作る際の元になるデータは論理的な単位ごとにSelectします。1回がだいたい数十件ぐらいです。 またその論理的な単位の分のデータをInsertしおわるごとにcommitしています(数十件ごとのcommitになります)。

  • 負荷試験の後重くなります。。。

    こんにちは Oracleサーバ負荷試験のため、下記2つの試験をやりました。 1、Commitなしで500万件のレコードをDBにINSERTしました。 2、Commitありで400万件のレコードをDBにINSERTしました。 その後、Delete from TABLEで中身を削除しましたが、 そのテーブルのSELECTがすごく重くなっているのは変わりませんでした。 心当たりがある方、解決法を教えていただけませんか? ちなみに、関係あるかどうか分かりませんが、そのテーブルの初期化サイズが7100KBぐらいなっています。ほかのテーブルは64KBぐらいですが、もしそれが原因だったら、最適化する方法ありますでしょうか? (できれば、テーブルの削除・再作成を避けたいです。)

  • 特定のスキーマのテーブルを一括削除したい

    おせわになります、 Oracleのデータベースで 特定のスキーマのテーブルを一括削除したい時の コマンドを探しているのですが、 ひとつずつ消すのは面倒なので、一括で消したいとかんがえております。 よろしくお願いします。

  • データ削除の方法

    オラクルのデータベース容量を減らす為に、SQL PLUSにてDELETE文を実行(テーブル別に)しました (テーブルの中身、全件削除ではなく条件に一致した不要なデータのみ削除) 条件に該当するデータは消えましたが、オラクルデータベース自体の容量が逆に増えていました 正しいデータの削除方法を教えて頂きたいのですが。宜しくお願いいたします データベース:ORACLE 9I DATABASE

  • OracleのIMPについて

    Oracle8iからOracle11gへのIMPについて教えてください。 現在、Oracleデータを8iから11gに移す作業を行っているのですが、特定のテーブルのみIMPの時間がかかっています。 4000万件のデータのIMPは1時間くらいで終わりますが特定のテーブルはデータ量が400万件にもかかわらず4時間くらいかかります。 原因等ありますでしょうか? ちなみに、IMPは、 imp XXXX/XXXX@XXXX file=TEST.DMP tables = TESTTABLE log = d:\test.log commit = Y ignore = Y の形式で行っています。

  • SQL、2つのテーブルで条件一致したものだけdeleteする方法は?

    オラクルSQLで質問です やりたいことは、 テーブルAから以下の条件に該当するデータを削除する。 基本的にはテーブルBの内容と比較して、一致したもの。 条件(全ての条件を満たすこと)  テーブルA.AAA = テーブルB.AAA  テーブルA.BBB = テーブルB.BBB  テーブルB.CCC > 0 調べたところ、SQLサーバでは以下のように from を2つ書いて実現できるようです。 が、今回はオラクルなので文法エラーになります。 delete FROM テーブルA FROM テーブルB where テーブルA.AAA = テーブルB.AAA AND テーブルA.BBB = テーブルB.BBB AND テーブルA.CCC > 0 ; commit; よろしくお願いします

  • INSERTしたテーブルデータの参照

    いつもお世話になっています。 早速ですが質問したいことがあります。 環境は、ORACLE11gです。 よろしくお願いします。 PL/SQLにて、テーブルAに対してINSERTを行い、テーブルAにINSERTした データを元にデータを作成し、テーブルBにINSERTをしたいと考えています。 COMMITは、プログラムの処理が全て終わった後に行います。 一応プログラムを作成し、想定どおりの動作を確認できたのですが、一点だけ 気になることがあります。 テーブルAにデータをINSERTしてから、COMMITせずに、テーブルBのデータを 作成するために、テーブルAのデータを取得します。その際、最初に登録した テーブルAのデータは、テーブルBを作成する際、必ず取得できるのでしょうか。 (一応作成したプログラムでは取得できていますが、必ず取得できるものなのか  を教えていただきたいです。) COMMITは、仕様上プログラムが全て終わった後にしか行えません。 質問は以上です。 質問文がごちゃごちゃして見難くてすみませんが、ご回答よろしくお願いします。

  • oracleの分割delete

    oracleに登録された数億件のデータを数日に分割して削除するため、 数億件のデータを5千件ずつ削除する方法を教えてください。 delete from テーブル名 where 条件 set rowcount = 5千; commit; これだと削除処理する件数が5千件であって、 先頭から5千件分見ることとは違うのでしょか? やりたいことは、 初日:一件目~5千件 二日目:5千1件目から一万件目 ・・・・・・ という感じで削除処理を行いたいです。 皆様の力を貸してください。宜しくお願いします。

  • DBの削除にあたって

    現在オラクルの9iを使用しています。 .sqlを使用して削除しようと思うのですが オラクルの9iのシステムが使用しているテーブルは そのままにしておき削除したくありません。 そこでオラクルの9iが使っているテーブル(スキーマ?)の名前を知りたいのですが?