如何正确索引Rails连接表迁移中的字段?

时间:2015-01-21 19:58:03

标签: ruby-on-rails

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

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

2 个答案:

答案 0 :(得分:3)

要完成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

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

index tree

答案 1 :(得分: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]应该是您的选择