在Rails中检索所有项目时如何优化总值计算

huangapple go评论47阅读模式
英文:

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:

  1. Using a query like @total_value = @items.sum(:value)
  2. Calculating the sum in Ruby with @total_value = @items.sum(&:value)

我考虑了两种方法:

  1. 使用像@total_value = @items.sum(:value)这样的查询
  2. 使用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:

  1. Using a query like @total_value = @items.sum(:value)
  2. 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
  • the number of records you're loading into memory, as that will have an effect on #sum (and later garbage collection)

huangapple
  • 本文由 发表于 2023年5月7日 01:51:11
  • 转载请务必保留本文链接:https://go.coder-hub.com/76190322.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定