在HABTM连接表上需要两个索引?

ssc*_*rus 32 postgresql indexing ruby-on-rails ruby-on-rails-3

一个简单的has_and_belongs_to_many关联:

Person has_and_belongs_to_many :products
Product has_and_belongs_to_many :persons
Run Code Online (Sandbox Code Playgroud)

两个以下索引以获得最佳性能有帮助吗?

add_index :person_products, [:person_id, :product_id]
add_index :person_products, [:product_id, :person_id]
Run Code Online (Sandbox Code Playgroud)

Dav*_* S. 49

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

add_index :person_products, [:person_id, :product_id], :unique => true
add_index :person_products, :product_id
Run Code Online (Sandbox Code Playgroud)

: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
Run Code Online (Sandbox Code Playgroud)

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

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

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

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


Hit*_*eeb 0

你只需要一个,除非你正在做unique

add_index :person_products, :person_id
add_index :person_products, :product_id
Run Code Online (Sandbox Code Playgroud)

或者对于两列都有索引

add_index :person_products, [:person_id, :product_id]
Run Code Online (Sandbox Code Playgroud)

这将有助于查询数据库中的这些列时的性能。这取决于您的查询是否包含两列或仅包含一列。

http://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/add_index

  • 我的理解是,如果查询先是“product_id”,然后是“person_id”,则它不会使用上面两列上的索引。 (4认同)