【问题标题】:Rails: Indexing and optimizing db queryRails:索引和优化数据库查询
【发布时间】:2013-07-06 18:25:03
【问题描述】:

这是我面临的问题。我有一个 has_one 配置文件的用户模型。我正在运行的查询是查找所有属于current_user 异性的用户,然后我按所有用户的last_logged_in 时间对结果进行排序。

问题在于 last_logged_in 是 User 模型的一个属性,而 gender 是 profile 模型的一个属性。有没有办法可以同时索引 last_logged_in 和性别?如果没有,如何优化查询以获得最快的结果?

【问题讨论】:

    标签: sql ruby-on-rails ruby-on-rails-3 indexing


    【解决方案1】:

    关于性别的索引不太可能有效,除非你正在寻找一个在表格中代表性非常低的性别,所以在 last_logged_in 上建立索引并让相反的性别在没有索引的情况下从结果集中被过滤掉.

    如果列与 (gender, last_logged_in) 上的索引可以用于准确识别需要哪些行,那么列在同一个表上可能是值得的,但即便如此,大部分性能改进将来自能够通过扫描索引以所需的排序顺序检索行。

    坚持为 last_logged_in 列建立索引,并寻找一个解释计划来证明用于满足排序顺序的索引。

    【讨论】:

    • 索引 last_logged_in 是不是一个聪明的主意?因为 last_logged_in 列将随着用户登录和注销而不断更新。这会增加维护索引的开销吗?它真的有助于加快查询速度吗?
    • 是的,我认为这很好——每个用户的值只会在他们登录时更新,这是一个“人类速度”事件,所以它不会每 10 秒或任何时间发生一次。如果优化器可以使用索引对结果集进行排序,则索引将是有价值的,因为替代方法是完全扫描表并对整个集进行排序。
    【解决方案2】:
    add_index :users, :last_logged_in
    add_index :profiles, :gender
    

    这将加快查找所有异性用户并按时间排序的速度。 不能有跨表索引。

    【讨论】:

    • 索引 last_logged_in 是不是一个聪明的主意?因为 last_logged_in 列将随着用户登录和注销而不断更新。这会增加维护索引的开销吗?它真的有助于加快查询速度吗?
    • 据我所知,您应该为执行搜索或排序的每一列建立索引。
    【解决方案3】:

    我只是为此编写查询

    在您的用户模型中

    def self.get_opposite_sex_users(current_user) 
      self.joins([:profile]).where("profiles.gender = ?", (current_user.profile.gender ==  'M') ? 'F' : 'M').order('users.last_logged_in DESC')
    end
    

    在您的操作中,您可以通过User.get_opposite_sex_users(current_user) 调用它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-08-30
      • 2015-03-25
      • 1970-01-01
      • 2013-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多