• ベストアンサー

大量のレコードを削除する方法

約100万件のレコードを削除したいのですが、 一気に削除するとDeviceがいっぱいとなり、問題です。 なので、1000件単位で削除できればと思うのですが、 何度も同じコマンドを送るのも気が遠くなるので、 なんとか自動化にしたいのですか、 簡単に1000件づつ、例えばfor文などを使って、自動的に削除していってくれるスクリプト(SQL文)を教えてください。  ちなみに今はSybaseですが、どんなデータベースでもかまいません。

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

  • ベストアンサー
  • YanYas
  • ベストアンサー率34% (26/75)
回答No.3

繰り返し同じコマンドを実行する方法として、isqlの場合は、 go の後に数字をいれることで、コマンドを繰り返し実行できます. 例えば insert table values ( 1 ) go 10 と指定すると、insert 文を10回繰り返し実行します。 また、set rowcount を使用すると、この後実行されるSQLの対象件数を指定することができます。 例えば set rowcount 1000 Select * from Table とすれば1000件が検索されます。 同じように set rowcount 1000 Delete Table とやれば100件、削除されるはずです。 ループを使用したい場合 While 文を使います. 前述のset rowcount とあわせて使うといいかもしれません。 set rowcount 1000 declare @count int select @count = 0 while @count < 100 begin delete Table [where条件] select @count = @count + 1 end 削除の対象となる条件がしていされていないので、テーブル先頭の方から適当に1000件消えてしまいます. 実際に作業される際は条件を指定する必要があると思います. また、Device がいっぱいになるとのことですが、トランザクションログ用のデバイスのことでいいですよね。 上記の方法では、いずれにせよトランザクションログはいっぱいになってしまうと思います.Dump tran 等で適宜対処する必要があるでしょう。 残したい行の条件が指定できるのであれば、 select into コマンドで 別テーブルに残したい行を移動し、元のテーブルを trancate table で削除、テーブルをリネームするのがいいと思います。select into や truncate table は大量にトランザクションログを出さないはずなので何度もコマンドを発行するよりいいと思います. 実際に処理を実行される場合は、必要なデータまで消さないように十分注意して行ってくださいね。 各コマンドの詳細はマニュアルを確認してください。 PDFのマニュアルのURLを参考URLに記入しておきます。 以上、がんばってください。

参考URL:
http://www.sybase.co.jp/product/manuals/index.html
momoraro
質問者

補足

YanYasさん、回答ありがとうございました。 早速使ってみようかと思いますが、2点ほど質問させてください。 while文を使用した際、1000件になるまでまわしていますが、一番初めにset rowcount 1000 を何故セットする必要があるのでしょうか? トランザクションがいずれにせよいっぱいになる(!)とのことでしたので、Dump tran を行いたいと思います。 ちなみに checkpoint コマンドはトランザクションログのクリアになりますか? 初心者の質問ですみません。 が、たいへん助かってます!

その他の回答 (2)

  • y_nakkan
  • ベストアンサー率46% (24/52)
回答No.2

#1です。別の方法を書きます。 必要なレコードをエクスポートし、表をdrop table で表削除した後、 新たに create table すれば、フラグメンテーションも解消されるので、良いかも! そして、エクスポートファイルからインポートすると。

  • y_nakkan
  • ベストアンサー率46% (24/52)
回答No.1

Sybaseですか。。 使ったことはないですが、他社DBからの類推で話をします。 100万件のレコードの削除ということですが、1つの表の全レコードを削除するのですか? それとも、不要なレコードだけ削除するのですか? 前者の場合、Oracleでは表内の全レコードを削除するSQL文が存在します。 "truncate table"文です。このSQL文はレコード管理ブロック部のみ初期化するので、 delete文より遥かに高速です。トランザクション処理をスキップしますので。 Sybaseにも同様なSQL文があればよいのですが。。 ----------------------- 「一気に削除するとDeviceがいっぱいとなる」とのことですが、おそらく、 トランザクション管理領域(Oracleでは「ロールバックセグメント」)がパンクするためでしょう。 DBのトランザクション設定を削除するときだけ、変更してみてはいかがですか? Oracle、DB2、informixでもそうですが、トランザクション処理を変更することができます。 トランザクション処理を一切行わない、いわゆる「ダーティリード・モード」にすれば、 「一気に削除するとDeviceがいっぱいとなる」現象は発生しないと思います。 一気に削除できるでしょう。 一度、マニュアルを見てはいかかでしょうか? もし、うまくいった場合、トランザクション設定を元に戻すことも忘れずに。

関連するQ&A

  • SQLiteで最も古いレコードのみの削除

    AndoroidでDBを使うのですが、考える動作のSQL文が作成できません。 テーブルTESTは以下のカラムを持ちます  ・ID - primary key not null  ・VALUE - not null テーブルTESTは最大で10件のレコードを保持します、11件目のレコードが発生したら 最も古い1件目のレコードを削除してから、11件目のデータを新しい10件目のデータとして テーブルに保存します。 そのために「最も古いレコード1件のみを削除する」というSQLを作成したいのですが、 考えたSQL文が正しくないと怒られてしまいます。 delete from TEST as A, (select * from TEST LIMIT 1)as B where A.ID=B.ID; この動作を1つのSQL文で行うのは不可能なのでしょうか?

  • アクティブなレコードを削除するSQL

    今現在開いているアクティブなレコード1件を削除するSQL というのはどのようにかけばいいのでしょうか?

  • Accessでデータベースからレコードを削除するには?

    Accessについての質問です。 データベースへのデータの登録はフォームを使って行なうようですが、データの削除はどうやってやるんでしょうか? レコード単位で削除したいです。

  • すべてのテーブルのすべてのレコードを削除する方法

    データベースを扱うプログラムに対してユニットテストを行いたいと思っています。 それぞれのテストが終了するごとにすべてのテーブル内のすべてのレコードを削除したいのですが、 delete from table_a; delete from table_b; delete from table_c; ... のように書くと、外部キー制約に引っかかってしまい削除できないことがあります。 短いSQL文で複数のテーブル内のレコードをすべて削除する方法はないのでしょうか? よろしくお願いします。 ちなみに、私が現在使っているDBMSはPostgreSQL 8.1です。

  • レコードのリセットは可能ですか?

    初心者です。よろしくお願いします。 50個ほどのフイールドがあるレコードの中身(各フィールド)を一気に消すようなSQL文などありませんでしょうか? auto_incrementで割り振っているID以外の中身をNULLもしくは空白にしたいと思っています。 これは、UPDATE文で一つずつ削除していくしかないのでしょうか? よろしくお願い致します。

    • ベストアンサー
    • MySQL
  • 一気に複数のレコードをinsertする方法について

    SQLのinsert文で一気に複数のレコードを挿入する方法ってありますか? SQL*LoaderとPL/SQL以外でお願いします。

  • レコードの分割削除

    いつも参考にさせて頂いてます。 今回の質問は、SQLのDelete文で100件ずつレコードを削除させるには、どうしたら良いでしょうか? という質問です。 過去の質問にも同じ質問があったのですが、当方の環境では実現できませんでした。 アプリケーションはVB6.0で作成しています。 (環境) OS :WinXP SP2 IDE:VB6.0 RDB:DB2

  • 一部重複しているレコードの削除

    一部だけ重複しているレコードの削除について教えてください。 検索したのですが、よくわかりませんでした。 f1       f2       f3       f4        f5 -----    -----    -----    -----     ----- 1       2005     T      20       A 2       2007     S      20      B 3       2003     S      20      C 4       2008     T      30      A 5       2005     T      30      C 6       2008     N      30      B 7       2007     T      20      D というようにあったとき、f3とf4が同じであった場合はf2の値がもっとも大きいもの一つを残して他のレコードを削除するというSQL文を考えています。 つまりこの場合にはf1が2,4,7のものを残したいのです。 この時のSQL文はどのようになるのでしょうか。 よろしくお願いします。

    • ベストアンサー
    • MySQL
  • レコードセットからレコードセットって作れますか?

    WindowsXP,VB6,SP5,で開発しています。 タイトルそのままなのですが、 ある事情で、まずはデータベース(Access)からレコードセットを作成しています。 そのレコードセットをもとに色々と抽出したいんです。 もし、データベースからSQL文で抽出するときみたいに、そのレコードセットを、 SUM(~とかGROUP化したりとかできればいいなあと思っているのですが、 その方法がわからず、2,3回遠回りしてレコードセットを作成してます。 レコードセットからレコードセットを作成することってできないのでしょうか? わかりにくくてすみませんが、どうぞよろしくお願いしますm(_ _)m

  • 関連レコードへの移動と関連レコードの新規作成

    甲というデータベースの山田太郎さんのレコードを表示している画面から、乙というデータベースの同じ山田太郎さんのレコードにボタン一つで飛ぶように、スクリプトを「関連レコードへ移動」のコマンドで作りました。これは問題なくできました。 甲の山田太郎さんの画面から、乙に山田太郎さんのレコードがあればそこに移動して、もし乙に、山田太郎さんのデータが存在しない場合に、乙に山田太郎さんの新規レコードを作るようにするには、どのようなスクリプトを作れば良いでしょうか。