[groonga-dev,01141] Re: 特定条件にマッチするレコードの一括削除

Back to archive index

Kouhei Sutou kou****@clear*****
2012年 12月 20日 (木) 16:14:44 JST


須藤です。

In <CA+vpKip4WwqgZG8ZD=NWfsd****@mail*****>
  "[groonga-dev,01140] Re: 特定条件にマッチするレコードの一括削除" on Thu, 20 Dec 2012 10:59:50 +0900,
  ongaeshi <ongae****@gmail*****> wrote:

>> > groonga 1.2.9リリース
>> > http://groonga.org/ja/blog/2011/12/29/release.html
>> >
>> > にて「レコードの一括削除に対応」というトピックを見つけました。
>> >
>> > 紹介されていた「特定条件にマッチするレコードの一括削除」を
>> > 【rroongaから】行うことは可能でしょうか?
>>
>> できません!
>>
>> なので、作ります!
>> ↓こんな感じのものを作ると思います。
>>
>>   table.delete do |record|
>>     # table.selectと同じように条件を指定する
>>   end
>>
>> Cレベルでカーソルを回すのでRubyレベルでループを回してレコー
>> ドを削除するよりも断然速くなると思います!
>>
> 
> おお!ありがたいですー。
> 実装されるのを楽しみにしております。

実装して、速度を測ってみたら言うほど変わりませんでした!

対象:
  るりまのデータ 47634件
削除するレコード数:
  24817件

select結果をeachしてdeleteしたときの削除時間:
  約104秒

deleteで条件をしてまとめて削除したときの削除時間:
  約95秒

なので、別の方法のご提案です。
削除前にインデックスを削除し、削除後にインデックスを再度追加
してください。こんな感じです。

  needless_records = table.select {...}
  Groonga::Schema.define do |schema|
    schema.table_change("Lexicon") do |table|
      table.remove_index("...")
    end
    ...
  end
  needless_records.each do |record|
    record.key.delete
  end
  Groonga::Schema.define do |schema|
    schema.table_change("Lexicon") do |table|
      table.add_index("...")
    end
    ...
  end

↑のようにした時の削除時間(インデックスの再構築を含む):
  約4.4秒


ということで、レコード削除処理はインデックスからの削除に時間
がかかっているので、それを一時的に止めれば速くなります。

ただし、deleteに条件を指定してまとめて削除する方法とインデッ
クスを一時的に止める方法は兼用できません。というのも、delete
対象のレコードを捜すためにインデックスを使うため、インデック
スを削除してあると削除対象のレコードを見つけるのが遅くなった
り、見つけられなくなったりするからです。


今回追加したdeleteでまとめて削除機能は便利なこともあると思う
ので残しておきます。

-- 
須藤 功平 <kou****@clear*****>
株式会社クリアコード <http://www.clear-code.com/> (03-6231-7270)

groongaサポート:
  http://groonga.org/ja/support/
パッチ採用はじめました:
  http://www.clear-code.com/recruitment/




groonga-dev メーリングリストの案内
Back to archive index