1

Ruby on Railsでは、すべてのメソッドがメソッドとhas_many :widgetsメソッドの両方を生成します。object.widgetsobject.widget_ids

後者の方法は、ActiveRecordオブジェクトの作成をバイパスし、はるかに高速なクエリを実行するため、非常に便利です。このオプションを使用するとクエリ速度を向上させることができます:selectが、Rubyは、整数の代わりにオブジェクトを生成するときに、より多くのメモリを割り当てます。

例えば

User has_many :historical_sessions:

>> Benchmark.measure { User.find(4).historical_sessions.map(&:id) }
HistoricalSession Load (131.0ms)   SELECT * FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0xbe805c0 @cutime=0.0, @label="", @total=1.996, @stime=0.0150000000000006, @real=2.09599995613098, @utime=1.981, @cstime=0.0>
(2.1 seconds)

>> Benchmark.measure { User.find(4).historical_session_ids }
HistoricalSession Load (34.0ms)   SELECT `historical_sessions`.id FROM `historical_sessions` WHERE (`historical_sessions`.user_id = 4)
=> #<Benchmark::Tms:0x11e6cd94 @cutime=0.0, @label="", @total=1.529, @stime=0.032, @real=1.55099987983704, @utime=1.497, @cstime=0.0>
(1.6 seconds)

(結果セットは67353オブジェクトです)

named_scopesを使用するときに同じ動作を発生させる方法はありますか?

例えば、

User named_scope :recent
User.recent (Exists)
User.recent_ids (Does not exist)

現在、名前付きスコープの結果セットでオブジェクトのIDを取得する方法は、HistoricalSession.recent.map(&:id)です。これは、上記の後者の例で行われていることと本質的に類似しており、明らかに効率的ではありません。最終的に必要なのはIDの配列だけであるのに、HistoricalSessionオブジェクト全体を構築したくありません。

別の実装は、新しい.findメソッドである可能性があります。たとえば、HistoricalSession.recent.find_attributes(:id)です。このメソッドは、selectステートメントを置き換えて、指定された値のみを選択し、ActiveRecordオブジェクトの作成を短絡して配列を返すだけです。

助言がありますか?これは簡単なプラグインでしょうか?

4

3 に答える 3

2

追加のメソッドを作成する代わりに、「ids」と呼ばれるアソシエーションプロキシにメソッドを作成して、たとえば次のようにすることができます。

User.named_scope :recent, ...
User.named_scope :admin, ...
User.recent.admin.ids

そして、ええ、それは私には賢明なプラグインのように聞こえます。書くのはそれほど難しいことではありません。

于 2009-03-27T10:38:40.650 に答える
1

私が最初にこの質問をしたので、Rails は .ids と .pluck の両方のメソッドを計算モジュールに追加しました。これらは当時の私の問題を解決したでしょう。

摘み取り: https://www.omniref.com/ruby/gems/activerecord/4.1.0/classes/ActiveRecord::Calculations##pluck

ID: https://www.omniref.com/ruby/gems/activerecord/4.1.0/classes/ActiveRecord::Calculations##ids

于 2014-05-17T00:56:12.253 に答える
0

ここで別の見方をするために - なぜあなたはこれについて気にしているのですか? どのくらいのメモリを使用していますか? 何かを最適化しようとしているようですが、行が数行しかない場合 (つまり、数百行未満) は、なぜあなたがこれについて心配しているのかわかりません。

問題がありますか、それとも想像していますか?

忘れないでください: http://en.wikipedia.org/wiki/Program_optimization#When_to_optimize

:-D

于 2011-06-29T16:48:10.093 に答える