処理に必要なレコードだけを取得する

 クエリの発行数が減らせるからといって、処理に必要のないレコードを大量に取得してしまうと処理速度が低下する場合がある。

 何でもかんでもEagerLoadで大雑把にレコードを取得する場合より、複数のクエリを実行することになっても処理に必要なレコードだけに絞り込んだ方が高速になる場合もある。

 EagerLoadすると、クエリを最小回数にできるのでそれだけで「パフォーマンスに配慮している」と安心してしまいがち。

User.where(id: user_ids).preload(user_items: :item)

 例えば、上記のコードはクエリの発行数を抑えられている、という点では効率的。(User、UserItems、Itemsの3つを参照するだけ)

 しかし、Userが所有するUserItemsは1Userあたり膨大な数になる可能性があり、トータルでは数千、数万のUserItemsが参照される可能性があるとすれば、その処理で大量のUserItemsが必要ない場合は参照しない方が処理が高速になる場合がある。

 何でもかんでもEagerLoadしておけば「パフォーマンスに配慮している」ことになるわけではなく、「処理に必要なレコードだけを最小回数のクエリで取得する」というスタンスが大事。

コメント