英文:
How to optimize total value calculation while retrieving all items in Rails
问题
I'm working on a Rails application where I need to display all items and the total value of those items.
Curently, in my ItemsController#index
, I retrieve all items with @items = current_user.items
and I want to calculate the total value.
我正在开发一个Rails应用程序,我需要显示所有物品以及这些物品的总价值。
目前,在我的ItemsController#index
中,我使用@items = current_user.items
检索所有物品,并且我想计算总价值。
I have considered two approaches:
- Using a query like
@total_value = @items.sum(:value)
- Calculating the sum in Ruby with
@total_value = @items.sum(&:value)
我考虑了两种方法:
- 使用像
@total_value = @items.sum(:value)
这样的查询 - 使用Ruby计算总和
@total_value = @items.sum(&:value)
I want to understand the pros and cons of these apporaches in terms of performance and efficiency.
我想了解这些方法在性能和效率方面的优缺点。
Is it better to use an additional query for summing values or is it acceptable to calculate the sum in Ruby?
使用额外的查询来计算总和是否更好,还是在Ruby中计算总和是可以接受的?
Are there any best practices or alternative solutions to optimize this process?
是否有任何最佳实践或替代方案来优化这个过程?
I would appreciate any answer. Thanks!
我会感激任何答案。谢谢!
英文:
I'm working on a Rails application where I need to display all items and the total value of those items.
Curently, in my ItemsController#index
, I retrieve all items with @items = current_user.items
and I want to calculate the total value.
I have considered two approaches:
- Using a query like
@total_value = @items.sum(:value)
- Calculating the sum in Ruby with
@total_value = @items.sum(&:value)
I want to understand the pros and cons of these apporaches in terms of performance and efficiency.
Is it better to use an additional query for summing values or is it acceptable to calculate the sum in Ruby?
Are there any best practices or alternative solutions to optimize this process?
I would appreciate any answer. Thanks!
答案1
得分: 0
Welcome to SO!
我认为,考虑到你提出的问题,你应该退后一步。
@items = current_user.items
在从数据库查询后将所有 item
记录加载到内存中。
一旦它们都在内存中,你正在考虑两个非常相似的选项:重新查询或循环。
这两个选项从大 O 表示法的角度来看本质上是相同的。你已经获取了所有记录,现在想对它们进行操作。
如果你只需要从 @items
获取 value
的总和,你最好的方法是只获取它:
current_user.items.sum(:value)
是一个单独的 SQL 调用:
> current_user.items.sum(:value).to_sql
=> SELECT SUM("items.value") FROM "items" where "items"."user_id" = 1
关于这两个选项,影响的因素包括:
- 你的数据库以及它在执行
SUM
操作时的速度,与 Ruby 在执行#sum
操作时的速度。- 在部署时,你还需要考虑服务器与数据库之间往返调用的额外开销,以及这是否超过了从
SUM
获取的速度提升。
- 在部署时,你还需要考虑服务器与数据库之间往返调用的额外开销,以及这是否超过了从
- 你加载到内存中的记录数量,因为这将影响
#sum
操作(以及后续的垃圾回收)。
英文:
Welcome to SO!
I think, given the question you're asking, you should back up one step.
@items = current_user.items
is loading all item
records into memory after a query of the database.
Once they are all in memory, you are considering two very similar options: re-query or loop.
Both those options are essentially the same in terms of big O notation. You've already fetched all the records, now you want to act on all of them.
If the only thing you need from @items
is the sum of the value
, your best approach is to only get that:
current_user.items.sum(:value)
is a single SQL call:
> current_user.items.sum(:value).to_sql
=> SELECT SUM("items."value") FROM "items" where "items"."user_id" = 1
In terms of the two options, the factors at play are:
- your database and how fast it is at
SUM
vs. how fast Ruby is at#sum
.- in deployment, you'll need to also think about the additional overhead of the round-trip call between the server and the database and whether that outweighs any speed boost from
SUM
- in deployment, you'll need to also think about the additional overhead of the round-trip call between the server and the database and whether that outweighs any speed boost from
- the number of records you're loading into memory, as that will have an effect on
#sum
(and later garbage collection)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论