包含在 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
.
你有几个选择:
- 预加载每个专业人员的所有评论并限制它们的输出(减少所需查询的数量但增加内存消耗,因为您可能预加载大量 AR 对象)。
- 延迟加载所需数量的评论(将查询数量增加 n+1,但减少潜在的内存消耗)。
- 使用原始 SQL.
编写自定义查询
如果您预加载所有内容,则无需进行太多更改。只需限制循环遍历每个 @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.
中阅读有关缓存的更多信息
我有以下问题。我需要对 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
.
你有几个选择:
- 预加载每个专业人员的所有评论并限制它们的输出(减少所需查询的数量但增加内存消耗,因为您可能预加载大量 AR 对象)。
- 延迟加载所需数量的评论(将查询数量增加 n+1,但减少潜在的内存消耗)。
- 使用原始 SQL. 编写自定义查询
如果您预加载所有内容,则无需进行太多更改。只需限制循环遍历每个 @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.
中阅读有关缓存的更多信息