rails多态关联中多列索引的顺序

时间:2017-02-13 20:38:02

标签: ruby-on-rails ruby activerecord polymorphic-associations

我有一个表格,其中包含我通过以下迁移生成的多态参考:

def change                  
  add_reference :table_name, :thing, polymorphic: true, index: true
end

当我运行迁移时,它会生成以下内容:

add_index "workflow_engine_task_bases", ["thing_type", "thing_id"], name: "index_workflow_engine_task_bases_on_thing_type_and_thing_id", using: :btree

为什么最左边的列是thing_type?对我来说,这似乎不是最理想的,因为它不那么具体。

2 个答案:

答案 0 :(得分:5)

这是Rails by Derek Prior中的commit,在为多态关联生成索引时,add_referencetype之前更新id。改变的理由如下:

  

在多列索引中首先使用类型列

     

add_reference可以在您使用时非常有用地添加多列索引   它添加一个多态参考。但是,在第一列   index是id列,不太理想。

     

[PostgreSQL docs] [1]说:

     

多列B树索引可以与查询条件一起使用   涉及索引列的任何子集,但索引最多   在领先(最左边)有限制时有效   列。

     

[MySQL docs] [2]说:

     

MySQL可以对测试所有内容的查询使用多列索引   索引中的列,或仅测试第一列的查询,   前两列,前三列,依此类推。如果你指定   索引定义中的列顺序正确,单个   复合索引可以加快几种查询的速度   表

     

在多态关系中,类型列更有可能   作为索引中的第一列比id列有用。就是我,我   更有可能查询没有id的类型,而不是我在id上查询   没有类型。

     

[1]:http://www.postgresql.org/docs/9.3/static/indexes-multicolumn.html

     

[2]:http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html

我认为在大多数情况下,这个顺序是有道理的。它允许您拥有一个在包括typeid或仅type的查询中表现良好的索引。

话虽如此,您的用例可能会有所不同,具体取决于您使用的数据库,数据集以及您计划运行的查询。最好的办法是在生产转储中分析最常见的用例,并相应地选择索引策略。

答案 1 :(得分:0)

来自http://apidock.com/rails/v4.2.7/ActiveRecord/ConnectionAdapters/SchemaStatements/add_reference

add_reference的源代码中:

add_index(table_name, polymorphic ? [type id].map{ |t| "#{ref_name}_#{t}" } : "#{ref_name}_id", index_options.is_a?(Hash) ? index_options : {}) if index_options

它只是从type位于id之前的数组进行映射。不确定为什么会这样设计,但最好只使用add_index

add_index(:table, [:thing_id, :thing_type])