39

一个简单的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]
4

3 回答 3

55

关闭 - 您很可能需要以下内容:

add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id

:unique => true不是严格要求的,它取决于让一个人与产品多次关联是否有意义。我会说,如果您不确定,您可能确实想要:unique旗帜。

索引结构的原因是所有现代数据库都可以使用第一个索引对 person_id 和 product_id 执行查询,而不管查询中指定的顺序如何。例如

SELECT foo FROM bar WHERE person_id = 1 AND product_id = 2
SELECT foo FROM bar WHERE product_id = 2 AND person_id = 1

被视为相同,并且数据库足够智能以使用第一个索引。

同样,使用 only 的查询person_id也可以使用第一个索引运行。多列 b 树索引可以使用比从原始声明左侧指定的列更少的列。

对于仅使用 的查询product_id,不能针对第一个索引执行此操作(因为该索引是用 person_id 在最左边的位置定义的)。因此,您需要一个单独的索引来单独启用对该字段的查找。

多列 b 树索引属性还扩展到具有更多列数的索引。如果您在 上有一个索引(person_id, product_id, favorite_color, shirt_size),则可以使用该索引来运行使用person_id(person_id, product_id)等的查询,只要顺序与定义匹配。

于 2013-03-05T01:26:11.697 回答
4

是的,它们很有帮助。但是你真的需要它们吗?这完全取决于你要用它做什么。索引(person_id,product_id)可以让您快速找到属于某个人的产品,但不会帮助您找到拥有某个产品的人。它还将强制执行 UNIQUE,因此您可能应该使用它。单独的索引将允许您找到属于个人的产品和拥有特定产品的人(person_id)(product_id)指数(person_id,product_id)(product_id,person_id)也适用于这两种情况,速度更快,但会占用更多空间,并且在插入/更新行时会花费更多(非常少)。时间和空间开销几乎总是值得的,除非你有一个写作多于阅读的基地。就我个人而言,我已经看到 9.2 中的仅索引扫描极大地受益于两列上的两个索引。所以你真正的选择是:

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)

于 2013-03-04T21:25:55.510 回答
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

于 2013-03-04T20:38:02.830 回答