包含在 Rails 中的查询

Queries with include in Rails

我有以下问题。我需要对 table 指定的专业人士进行大量查询,但我需要优化查询,因为我为每个专业人士调用关联的 table。

但我有两个相关的问题 table:评论和关税。

评论:

我需要为每个专业打3条评论。我尝试:

@professionals.includes(:comments).where(:comments => { type: 0 } ).last(3)

查询只带3个专业的问题,不是我需要的,所有专业只有3条评论,type为0。

当我尝试时:

@professionals.includes(:comments).where(:comments => { type: 0 } )

当我需要所有有评论或没有评论的专业人士时,结果只有有(所有)评论的专业人士。但是如果专业人士有评论我只需要类型为零的最后三个评论

关税:

对于关税我有类似的问题,在这种情况下我需要每个专业的最后 4 个关税。我尝试:

@professionals.includes(:tariffs).last(4)

但只带来了最后4位专业人士。

型号:

class Comment < ActiveRecord::Base
      belongs_to :client
      belongs_to :professional

end

class Professionals < ActiveRecord::Base
      has_many :comment

end

您不能对 ActiveRecord 中的加入 table 使用限制。 limit 应用于第一个关系,在本例中恰好是 @professionals.

你有几个选择:

  1. 预加载每个专业人员的所有评论并限制它们的输出(减少所需查询的数量但增加内存消耗,因为您可能预加载大量 AR 对象)。
  2. 延迟加载所需数量的评论(将查询数量增加 n+1,但减少潜在的内存消耗)。
  3. 使用原始 SQL.
  4. 编写自定义查询

如果您预加载所有内容,则无需进行太多更改。只需限制循环遍历每个 @professional.

的评论数
@professionals.each do |professional|
  @professional.comments.limit(3)
end

如果您只延迟加载您需要的内容,那么您可以将 limit 作用域应用于评论关系。

@professionals.all
@professionals.each do |professional|
  @professional.comments.where(type: 0).limit(3)
end

编写自定义查询有点复杂。但是您可能会发现它的性能可能会降低,具体取决于您必须进行的连接数量以及您的 table 的索引程度。

我建议您采用方法二,并使用查询和片段缓存来提高性能。例如:

- cache @professionals do
  - @professionals.each do |professional|
    - cache professional do
      = professional.name

这种方法会第一次命中数据库,但后续加载评论后将从缓存中读取,避免数据库命中。您可以在 Rails Guides.

中阅读有关缓存的更多信息