【问题标题】:Need two indexes on a HABTM join table?在 HABTM 连接表上需要两个索引?
【发布时间】:2013-02-19 01:51:07
【问题描述】:

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

【问题讨论】:

    标签: ruby-on-rails ruby-on-rails-3 postgresql indexing


    【解决方案1】:

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

    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
    

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

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

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

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

    【讨论】:

      【解决方案2】:

      是的,它们很有帮助。但是你真的需要它们吗?这完全取决于你要用它做什么。 (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)

      【讨论】:

        【解决方案3】:

        你只需要一个,除非你在做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

        【讨论】:

        • 我的理解是,如果查询通过product_id,然后person_id,它不会使用上面两列的索引。
        猜你喜欢
        • 2013-08-07
        • 1970-01-01
        • 1970-01-01
        • 2019-04-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2019-06-06
        相关资源
        最近更新 更多