何时在Rails中添加表中的索引

TK.*_*TK. 129 mysql activerecord ruby-on-rails

我有一个关于Rails数据库的问题.

  • 我应该为所有外键添加"索引",如"xxx_id"吗?
  • 我应该在自动创建的"id"列中添加"index"吗?
  • 我应该在自动创建的"id"列中添加"index(unique)"吗?

  • 如果我一次向两个外键添加索引(add_index (:users, [:category, :state_id])会发生什么?这与为每个键添加索引有何不同?

    class CreateUsers < ActiveRecord::Migration
      def self.up
        create_table :users do |t|
          t.string :name
          t.integer :category_id 
          t.integer :state_id
          t.string :email
          t.boolean :activated
          t.timestamps
        end
      # Do I need this? Is it meaningless to add the index to the primary key?
      # If so, do I need :unique => true ?
      add_index :users, :id 
      # I don't think I need ":unique => true here", right?
      add_index :users, :category_id # Should I need this?
      add_index :users, :state_id # Should I need this?
      # Are the above the same as the following?
      add_index (:users, [:category, :state_id])
      end
    end
    
    Run Code Online (Sandbox Code Playgroud)

到目前为止答案很棒.补充问题.

  • 我应该为xxx_id添加"index with unique",对吗?

jig*_*fox 173

我应该为所有外键添加"索引",如"xxx_id"吗?

它会更好,因为它加速了本专栏中的排序搜索.外键是搜索了很多东西.

从rails版本5开始,将自动创建索引,有关详细信息,请参阅此处.

我应该在自动创建的"id"列中添加"index"吗?

不,这已经由rails完成了

我应该在自动创建的"id"列中添加"index(unique)"吗?

不,和上面一样

如果我一次向两个外键添加索引(add_index (:users, [:category_id, :state_id])会发生什么?这与为每个键添加索引有何不同?

然后索引是两列的组合索引.这没有任何意义,除非你想要同时为一个category_id 一个state_id(它应该category_id不是category)的所有条目.

像这样的索引会加快以下请求:

# rails 2
User.find(:all, :conditions => { :state_id => some_id, :category_id => some_other_id })

# rails 3
User.where(:state_id => some_id, :category_id => some_other_id)
Run Code Online (Sandbox Code Playgroud)

哪里

add_index :users, :category_id
add_index :users, :state_id
Run Code Online (Sandbox Code Playgroud)

将加快这些要求:

# rails 2+3
User.find_by_category_id(some_id)
User.find_by_state_id(some_other_id)

# or
# rails 2
User.find(:all, :conditions => {:category_id => some_id})
User.find(:all, :conditions => {:state_id => some_other_id})

# rails 3
User.where(:category_id => some_id)
User.where(:state_id => some_other_id)
Run Code Online (Sandbox Code Playgroud)

我应该为xxx_id添加"index with unique",对吗?

不,因为如果你这样做,只有一个用户可以在一个类别,但类别的意思是,你可以把更多的许多用户归为一类.在你的User模型中你有这样的东西belongs_to :category,在你的类别模型中有类似的东西has_many :users.如果你有has_many关系,那么这个foreign_key领域不能是唯一的!

有关这方面的更多详细信息,您应该看看tadman的好答案.

  • 很好的答案.补充问题.我应该为xxx_id添加"index with unique",对吗? (3认同)

tad*_*man 110

索引可能是一个棘手的,微妙的事情,但有一些适用的一般规则可以确定哪些使用更容易.

首先要记住的是索引可以以多种方式工作.A,B,C上的索引也适用于A,B和A,因此如果正确订购,您可以将索引设计得更加通用.电话簿以姓氏,名字为索引,因此您可以通过姓氏或姓氏和名字的组合轻松查找人员.但是,你不能用他们的名字直接查找它们.你需要一个单独的索引.电话号码也是如此,你也需要索引.

考虑到这一点,有许多事情将决定如何创建索引:

  • 如果你有一个belongs_to- has_many关系配对,你需要在使用的外键上有一个索引.
  • 如果您订购了记录,并且有大量的记录将被分页,您应该将该订单列添加到索引的末尾.
  • 如果您有has_many :through关系,则您的连接表应该在连接中涉及的两个属性上都具有唯一索引作为复合键.
  • 如果使用用户名或电子邮件等唯一标识符直接获取记录,则应该是唯一索引.
  • 如果has_many使用作用域从关系中获取记录集,请确保存在一个索引,该索引包含该has_many顺序中的外键和作用域列.

索引的目标是消除在数据未正确索引时发生的可怕的"表扫描"或"文件排序"操作.

简单来说,查看应用程序生成的查询,并确保以该顺序表示WHEREHAVING条件和ORDER BY子句中引用的列.


Wil*_*lor 11

  • 始终索引外键
  • 始终索引要订购的列
  • 所有独特的字段(以确保唯一性在数据库级别实例迁移.add_index :users, :email, unique: true)
  • 如果你按两件事订购,或者用两件事来搜索,例如: order by [a, b]或者find where( a and b ),你需要一个双索引:

具体例子:

如果你有:

default_scope :order => 'photos.created_at DESC, photos.version DESC'
Run Code Online (Sandbox Code Playgroud)

你应该添加:

add_index :photos, [:created_at, :version]
Run Code Online (Sandbox Code Playgroud)

注意:索引会占用磁盘上的额外空间,并使创建和更新每条记录的速度变慢,因为它必须重建每个索引.

信用:

https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes,轨道-当用户订购,您应该增加一个索引表created_at?,以及上面的答案.