1

Rails アプリケーションのある時点で、キャッシュから多数の ActiveRecord オブジェクトを取得します。ただし、これらのレコードの一部は、キャッシュに保存された後にデータベース自体から削除された可能性があるため、レコードをループして、それぞれが存在するかどうかを確認します。これにはかなりの時間がかかります。これを行うより効率的な方法はありますか?

4

4 に答える 4

2

データベースからレコードが削除されたときに、キャッシュからレコードを削除しない理由はありますか?

これらのレコードをキャッシュに保存し、dbと同期させる必要がある場合は、それらをdbから削除するときに、それらの存在もキャッシュから削除するようにしてください。これにより、コストのかかるクエリを節約できます。後で冗長データを確認してください。

于 2012-11-29T04:43:10.977 に答える
1

これは、データベース設計の問題と見なすこともでき、実際にはレールの問題ではありません。その観点から、一意のインデックスを持つAUTO INCREMENTフィールドをテーブルに追加できますか?

アクティブレコードクエリインターフェイスは、レコードの存在チェックを実行する場合でも、最終的にはデータベースに依存してルックアップを行う必要があります。したがって、インターフェースがどれほど優れていても、dbが多くの作業を行わなければならない場合は時間がかかり、レールの「障害」ではありません。dbが必要なレコードを検証するのをできるだけ速くします。

oracleに精通している場合、これは、後で既存のレコードを検証できるようにoraclerowidをクエリに格納するのと同じ考え方です。

Dannyが指摘しているように、大量のレコードをキャッシュして、後でそれらを使用することは、アプリにとって悪い考えです。あなたはあなたの記録を読んですぐに処理することができますか?

これらの提案はどちらも簡単な修正ではありません。

于 2012-11-29T02:53:59.687 に答える
0

キャッシュからの結果に、関心のあるレコードの主キーが含まれている場合、データベースからそれらのキーだけを選択して何が返されるかを確認することで、結果を非常に簡単にフィルター処理できます。その後、古いレコードを追い出すだけで準備完了です。

results_from_cache = $redis.get("users")

cached_user_ids = results_from_cache.map(&:id)
actual_user_ids = User.where(id: user_ids).pluck(:id)

results_minus_stale = results_from_cache.select do |user|
  actual_user_ids.include?(user.id)
end
于 2012-11-29T03:18:27.073 に答える
0

チェックしているレコードの数が非常に多い場合は、一括転送を行うことで、それらを 1 つずつ配送するコストを償却できる場合があります。一時テーブルを作成し、そこに行を大量に挿入します。キャッシュから引き出して、元のテーブルに対して一時テーブルを結合します。その後、DBMS がループ処理を行います。

于 2012-11-29T03:10:04.600 に答える