4

PostgreSQL 9.0.x DBにテーブルがあり、cached_projects主にRailsアプリを介してアクセスします。このスキーマは次のようになります。

create_table "cached_projects", :force => true do |t|
  t.string   "name",                               :null => false
  t.datetime "created_at",                         :null => false
  t.datetime "updated_at",                         :null => false
  t.boolean  "localization",    :default => false, :null => false
  t.integer  "base_project_id"
end

テーブルには、 N分ごとに実行され、次のことを実行するRakeタスクが入力されます。

  • SOAP Webサービスからすべてのプロジェクトレコードを照会します(このコンテキストでの「プロジェクト」は、名前(文字列)と2つのブールフィールドと整数フィールドで構成されます)。
  • DB内のプロジェクトのリストをSOAP結果と同期し、SOAP結果に存在しなくなったレコードを破棄し、見つかった新しいレコードを追加します。

この定期的な同期を行うための最も効率的な方法は何ですか?DB内の行が、余分なものがなく、SOAP結果で指定されたレコードと正確に一致することが重要です。

2つの解決策を考えることができますが、どちらが最速かはわかりません(数万のレコードがあり、できるだけ頻繁に同期したいので、パフォーマンスが問題になります)。

  1. 各同期中に、すべての行を削除cached_projectsし、SOAPサービスを介して検出された各プロジェクトの新しい行を挿入します。

    これにより、まったく同じデータセットを持つという目標が達成されますが、それらの大部分が変更されないと仮定すると、DB内で毎回最大50,000行を削除するのにどれくらいの費用がかかりますか?DBにこれほど多くの「チャーン」があることの欠点はありますか?

  2. 各同期中に、のすべての行をSELECTcached_projectsして、一時的なハッシュ変数に格納します。SOAPレコードをループし、各レコードについて、(一時的なハッシュを使用して)すでにDBにあるかどうかを確認し、見つかったDBレコードのIDのリストを保持して、DBに残せるようにします。すべてを比較した後、新しいレコードの行をINSERTし、テーブルに存在しなくなったレコードの行をDELETEします。

    これは私の現在のソリューションであり、データを正確にミラーリングしますが、Rakeタスク内のすべてのレコードを比較することはかなり計算集約的であり、同期ごとに約3〜5分かかります。(実際には、最初の同期では、DBテーブルが空の場合は高速ですが、後続の同期では、すべての行と比較する必要があり、低速です。)

私は他の提案、またはこれらのアイデアのいずれかに対する改善を受け入れています。これまで、アプリケーションコード(Rubyベースのrakeタスク)内のソリューションを検討してきましたが、DB自体にあまり詳しくないため、より多くのロジックをDB自体にプッシュするアイデアにも興味があります。物事の。

4

1 に答える 1

1

最初の同期が後続の同期よりも高速である場合、これは、すべてのデータをデータベースに挿入する方が、各データを比較して既存のテーブルを変更するよりも高速であることを意味します。

TRUNCATE削除する代わりに、テーブル内のすべてのレコードを削除してから、すべてのレコードをテーブルに挿入するために使用することをお勧めします。

http://en.wikipedia.org/wiki/Truncate_(SQL)

于 2013-03-18T05:32:56.663 に答える