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

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

  • 我是否应该将“ index”添加到所有类似“ xxx _ id”的外键?
  • 我是否应该将“ index”添加到自动创建的“ id”列?
  • 我应该添加“索引(唯一)”到自动创建的“ id”列?

  • 如果我同时向两个外键添加索引(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
    

Great answer so far. Additional question.

  • I should add "index with unique" for xxx_id, right?
32293 次浏览

我是否应该将“ index”添加到所有类似“ xxx _ id”的外键?

这样会更好,因为它加速了本专栏中的排序搜索。外国钥匙是需要大量搜索的东西。

由于 Rails 版本5将自动创建索引,更多信息请参见 给你

我是否应该将“ index”添加到自动创建的“ id”列?

不,这已经是铁路公司做的了

我应该添加“索引(唯一)”到自动创建的“ id”列?

不,和上面一样

如果我同时向两个外键添加索引(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)

在哪里

add_index :users, :category_id
add_index :users, :state_id

将加速这些请求:

# 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)

我应该为 xxx _ id 添加“ index with only”,对吗?

不,因为如果您这样做,只有一个用户可以在一个类别,但类别的意思是,您可以把更多的 很多用户到一个类别。在你的 User模型中,你有类似 belongs_to :category的东西,在你的类别模型中,有类似 has_many :users的东西。如果你有一个 has_many关系的 foreign_key字段不能是唯一的!

对于更详细的信息,你应该看看 Tadman的伟大的 回答

索引可能是一件棘手而微妙的事情,但是有一些适用的一般规则可以使决定使用哪个索引变得更加容易。

首先要记住的是,索引可以以多种方式工作。A、 B、 C 上的索引也适用于 A、 B 和简单的 A,因此如果排序正确,可以将索引设计得更加通用。该电话簿是索引的姓氏,名字,所以你可以很容易地查找人们的姓氏,或姓氏和名字的组合。然而,你不能直接通过他们的名字来查找他们。你需要一个单独的索引。对于电话号码也是一样,您还必须编制索引。

记住这一点,有许多事情将决定您如何创建索引:

  • 如果有 belongs_to-has_many关系对,则需要对所使用的外键建立索引。
  • 如果您对记录进行排序,并且有大量的记录将被分页,那么您应该将该排序列添加到索引的末尾。
  • 如果您有一个 has_many :through关系,那么您的联接表应该对作为复合键的联接所涉及的两个属性都有一个唯一的索引。
  • 如果你直接使用用户名或电子邮件等唯一标识符获取记录,那么这应该是一个唯一的索引。
  • 如果使用作用域从 has_many关系中获取记录集,请确保有一个包含 has_many外键和作用域列的索引。

使用索引的目的是消除数据索引不正确时可怕的“表扫描”或“文件排序”操作。

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

  • 始终索引外键
  • 始终索引您将要排序的列
  • 所有唯一字段(以确保数据库级别的唯一性。示例迁移: 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'

你应该加上:

add_index :photos, [:created_at, :version]

注: 索引占用磁盘上的额外空间,使得创建和更新每条记录变得更慢,因为它必须重新构建每个索引。

图片来源:

Https://tomafro.net/2009/08/using-indexes-in-rails-choosing-additional-indexes ,当用户进行排序时,是否应该向表中添加一个 Index?,以及上面的答案。