where语句的Rails-SQL效率

where语句的Rails-SQL效率,sql,ruby-on-rails,ruby-on-rails-3,performance,Sql,Ruby On Rails,Ruby On Rails 3,Performance,有没有更有效的方法来执行以下代码的Rails SQL语句 它将在整个网站上被调用,根据用户是否被阻止来隐藏某些内容或用户,因此它需要相当高效,否则它也会减慢其他一切 users.rb文件: def is_blocked_by_or_has_blocked?(user) status = relationships.where('followed_id = ? AND relationship_status = ?', user.id, relationship_

有没有更有效的方法来执行以下代码的Rails SQL语句

它将在整个网站上被调用,根据用户是否被阻止来隐藏某些内容或用户,因此它需要相当高效,否则它也会减慢其他一切

users.rb文件:

  def is_blocked_by_or_has_blocked?(user)
    status = relationships.where('followed_id = ? AND relationship_status = ?', 
          user.id, relationship_blocked).first ||
        user.relationships.where('followed_id = ? AND relationship_status = ?', 
          self.id, relationship_blocked).first
    return status
  end
在该代码中,
relationship\u blocked
只是一个整数的抽象,便于以后阅读

在视图中,我这样调用此方法:

- unless current_user.is_blocked_by_or_has_blocked?(user)
  - # show the content for unblocked users here
编辑

这是一个示例查询。。它在找到第一个实例后停止(无需检查反向关系)


您可以将其更改为仅运行一个查询,方法是在查询中使用(x,y,z)语句中的
(这是通过将id数组传递给:followerd\u id完成的)。另外,通过使用
.count
,您可以绕过Rails为结果关系实例化模型实例,这将使事情更快(在内存中传递的数据更少):


编辑-让它看起来是双向的


您可以将其更改为仅运行一个查询,方法是在查询中使用(x,y,z)
语句中的
(这是通过将id数组传递给:followerd\u id完成的)。另外,通过使用
.count
,您可以绕过Rails为结果关系实例化模型实例,这将使事情更快(在内存中传递的数据更少):


编辑-让它看起来是双向的


关系_基本上是“真”还是“假”,或者它可以占用其他状态(0、1、2、3…)?此外,当显示此视图时,在日志文件中(例如development.log,如果您处于“开发”环境中),您应该看到完整的SQL语句。出于好奇,它当前运行需要多少毫秒?@normalocity:它可以占用几个整数状态中的一个。运行语句通常需要0.1-0.2ms,但这是在没有很多记录的数据库上进行的。它正在搜索的所有列都被编入索引,因此更重要的是语句的效率。关系是否基本上为“真”或“假”,或者是否有其他状态(0、1、2、3…)可以占用?此外,当您显示此视图时,在日志文件中(例如development.log,如果您处于“开发”中)环境)您应该看到完整的SQL语句。出于好奇,它当前运行需要多少毫秒?@normalocity:它可以占用几个整数状态中的一个。运行语句通常需要0.1-0.2ms,但这是在没有很多记录的数据库上进行的。它正在搜索的所有列都被编入索引,因此问题在于语句的效率。但是,这如何能够检查反向关系呢?例如,现在这只会检查当前用户(或您调用该方法的任何用户)是否有包括他自己或其他用户的关系,但您也需要检查其相反的关系,即
用户关系。其中…
啊,好的,在您的示例中我没有注意到这一点。但是,如果第一个查询返回nil,它将运行第二个查询。我想这取决于这对你有多重要。您仍然可以绕过它,通过直接在
关系
上运行与我的示例类似的查询,而不是在
关系
用户.relationships
上运行类似的查询,并将其转换为单个查询,只需将更多内容传递给它(
。其中(:user\u id=>[user.id,self.id])
).但如何检查反向关系?例如,现在这只会检查当前用户(或您调用该方法的任何用户)是否有包括他自己或其他用户的关系,但您也需要检查其相反的关系,即
用户关系。其中…
啊,好的,在您的示例中我没有注意到这一点。但是,如果第一个查询返回nil,它将运行第二个查询。我想这取决于这对你有多重要。您仍然可以绕过它,通过直接在
Relationship
而不是
relationships
user.relationships
上运行与我的示例类似的查询,将其转换为单个查询,只需将更多内容传递给它(
。其中(:user\u id=>[user.id,self.id])
)。
Relationship Load (0.2ms)  SELECT "relationships".* FROM "relationships" WHERE ("relationships".follower_id = 101) AND (followed_id = 1 AND relationship_status = 2) LIMIT 1
def is_blocked_by_or_has_blocked?(user)
  relationships.where(:followed_id => [user.id, self.id], :relationship_status => relationship_blocked).count > 0
end
Relationship.where(:user_id => [user.id, self.id], :followed_id => [user.id, self.id], :relationship_status => relationship_blocked).count > 0