一个简单的has_and_belongs_to_many
关联:
Person has_and_belongs_to_many :products
Product has_and_belongs_to_many :persons
以下以下索引是否有助于获得最佳效果?
add_index :person_products, [:person_id, :product_id]
add_index :person_products, [:product_id, :person_id]
答案 0 :(得分:48)
关闭 - 您最有可能想要以下内容:
add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id
:unique => true
并非严格要求,取决于是否有人多次与产品相关联。我会说,如果你不确定,你可能做想要:unique
标志。
索引结构的原因是所有现代数据库都可以使用第一个索引在person_id和product_id上执行查询,而不管查询中指定的顺序。 E.g。
SELECT foo FROM bar WHERE person_id = 1 AND product_id = 2
SELECT foo FROM bar WHERE product_id = 2 AND person_id = 1
被视为相同,数据库足够智能,可以使用第一个索引。
同样,也可以使用第一个索引运行仅使用person_id
的查询。多列b树索引可以使用比原始声明左侧指定的列少的列。
对于仅使用product_id
的查询,不能对第一个索引执行此操作(因为该索引是在最左边的位置使用person_id定义的)。因此,您需要一个单独的索引来单独启用该字段的查找。
多列b-tree索引属性还扩展到具有更多列数的索引。如果您在(person_id, product_id, favorite_color, shirt_size)
上有索引,则只要订单与定义匹配,就可以使用该索引使用person_id
,(person_id, product_id)
等运行查询。
答案 1 :(得分:3)
是的,他们很有帮助。但你真的需要它们吗?这一切都取决于你将要用它做什么。
(person_id,product_id)
上的索引将允许您快速查找属于人的产品,但不会帮助找到拥有某种产品的人。它还将强制执行UNIQUE,因此您可能应该使用它。
(person_id)
和(product_id)
上的单独索引将允许您查找属于个人和拥有特定产品的人的产品。
(person_id,product_id)
和(product_id,person_id)
上的索引也适用于这两种情况,速度会更快,但会占用更多空间,插入/更新行时会占用更多(非常少)。时间和空间开销几乎总是值得的,除非你有一个基础,你写的比阅读更频繁。
就个人而言,我已经看到9.2中的Index Only Scans从两列的两个索引中受益匪浅。
所以你真正的选择是:
unique index on (col 2, col 1), unique index on (col 1, col 2)
和
unique Index on (col 1, col 2), index on (col 2)
答案 2 :(得分:0)
除非你正在做unique
add_index :person_products, :person_id
add_index :person_products, :product_id
或两列的索引
add_index :person_products, [:person_id, :product_id]
这将有助于查询数据库上的那些列时的性能。如果它包含两列或只包含一列,它将取决于您的查询。
http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index