【问题标题】:How to properly index fields on a Rails join table migration?如何正确索引 Rails 连接表迁移上的字段?
【发布时间】:2015-01-21 19:58:02
【问题描述】:

Rails 4 引入了用于生成连接表迁移的功能:

bin/rails generate migration CreateTeamsUsersJoinTable team user

这会产生以下文件:

class CreateTeamsUsersJoinTable < ActiveRecord::Migration
  def change
    create_join_table :teams, :users do |t|
      # t.index [:team_id, :user_id]
      # t.index [:user_id, :team_id]
    end
  end
end

您可以看到索引已被注释掉。为什么是这样?我应该决定要使用哪一个吗?或者他们是否暗示索引是可选的?我想确保每个字段都有某种索引以避免性能问题,但我不确定如何正确定义这些字段的索引。

【问题讨论】:

    标签: ruby-on-rails


    【解决方案1】:

    要完成 xlembouras 答案,您可以根据查询表的方式做出选择。

    例如,如果您有一个显示给定团队的用户的视图,则查询将如下所示:

    SELECT user.name FROM team_users tu 
    INNER JOIN users u 
    ON tu.user_id = u.id
    WHERE tu.team_id = X
    

    这得益于t.index [:team_id, :user_id] 而不是t.index [:user_id, :team_id]

    数据库将仅在第一个索引上使用一次索引查找来检索用户 ID

    如果您有一个显示给定用户的团队的视图,则查询将类似于以下内容:

    SELECT team.name FROM team_users tu 
    INNER JOIN team t 
    ON tu.team_id = t.id
    WHERE u.user_id = X
    

    这得益于t.index [:user_id, :team_id] 而不是t.index [:team_id, :user_id]

    数据库将仅在第一个索引上使用一次索引查找来检索团队 ID

    这是因为组合索引的存储方式:

    【讨论】:

    • 阅读您的好答案后,我发现复合索引(AKA 复合索引,双索引)在简单的连接表中没有意义。由于连接表用于单向查询数据,如您的示例所示,因此我们应该使用简单的单列索引。我们永远不会查询特定的用户 id 和团队 id,因为这只会给我们关联行,没有额外的数据。还是我弄错了……?
    【解决方案2】:

    我不得不说,这背后的意图是让您选择更适合您的策略。这通常是一个有两个标准的决定

    • 索引会增加多少开销
    • 如何查询数据库

    因此他们无法为您做出该决定,并将索引开销作为惯例添加。

    为了做出这个决定,您需要知道您打算如何查询您的数据库。在 MySQL 中,复合索引可用于一组查询。 multiple-column index

    column_a, column_b, column_c 上的索引将用于查询

    • 所有三个字段一起
    • column_a 一个人
    • column_acolumn_b 在一起

    所以还是有区别的

    t.index [:team_id, :user_id]
    

    t.index [:user_id, :team_id]
    

    您需要的实际完整索引集是

    t.index [:team_id, :user_id]
    t.index :user_id
    

    t.index [:user_id, :team_id]
    t.index :team_id
    

    为了处理所有三种情况的索引。

    示例

    如果您发现您的应用使用更频繁的查询,例如

    user.teams 翻译成

    select * from teams where user_id = X

    user_id(或user_id, team_id)上的索引会很方便

    所以t.index [:user_id, :team_id]应该是你的选择

    【讨论】:

    • 谢谢,这真的很有帮助,但我仍然很难理解。您能否详细说明这些示例之间的差异?例如,team.usersuser.teams 的组合是否更好?
    • 另外,假设我在开发中使用 SQLite,在生产中使用 PostgreSQL...根据支持的索引应该使用哪些索引有区别吗?
    • 请阅读use-the-index-luke.com/sql/where-clause/the-equals-operator/… 顺便说一句,SQLite 和 PostgreSQL 没有区别。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-13
    • 2011-05-21
    • 2015-03-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-08
    相关资源
    最近更新 更多