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/