PostgreSQL复杂索引类型和排序

时间:2013-03-08 19:56:32

标签: ruby-on-rails postgresql ruby-on-rails-3.2 indexing postgres-ext

在过去的几天里,我一直在做索引的重读,我正试图找出正确的方法来索引我有很多约束的查询。我使用postgres_ext gem来支持数组数据类型和GIN和GIST索引类型。

我有两个问题

.where("a_id IN (?) and b = ? and active = ? and ? != ALL(c) and ? = ANY(d)")
.where("a_id =? and active =? and ? != ALL(c)")

c和d是整数数组

我计划添加的索引:

 add_index :deals, [:a, :b], :where => "active = true"
 add_index :deals [:c, :d], :index_type => :gin, :where => "active = true"

postgres会在第一个查询中使用这两个多列索引吗?

数组数据类型是否应始终采用“gin”索引类型?或者你也可以将它们放在b树索引中吗?

最后在第一个索引中是否会在两个查询中使用'a'?

其他信息:

我正在使用PostgreSQL 9.1.3

create_table "table", :force => true do |t|
 t.integer  "a_id"    ##foreign key
 t.string   "title"
 t.text     "description",    :default => ""
 t.boolean  "active",           :default => true
 t.datetime "created_at",      :null => false
 t.datetime "updated_at",    :null => false
 t.integer  "b",
 t.integer  "c", :limit => 8,   :array => true
 t.integer  "d",  :array => true
end

1 个答案:

答案 0 :(得分:4)

关于数组和GIN,您可以拥有数组的b树索引,但它对“array contains element”之类的操作没有用。您需要GIN或GiST,并且只支持GIN作为所有数组类型的内置索引。

您还可以将intarray extension及其GiST索引类型用于整数数组,这些数组在写入负载下性能会更好,但在读取负载下会更差。

至于确定Pg是否会使用两个索引,最好的方法是使用EXPLAIN ANALYZE并查看。通过启用log_statement或从带有SQL登录的Rails日志获取Rails在PostgreSQL日志中执行的语句。然后使用psqlexplain analyze中运行它。或者,使用auto_explain extension在运行时捕获有关查询的性能报告。

我觉得你会发现Pg无法在同一个过滤器中组合GiST或GIN和b树索引。组合索引需要位图索引扫描,而IIRC仅适用于两个b树索引。您可能需要将额外的列添加到GiST或GIN索引,但这会极大地增加索引大小,可能不值得。

您确实需要使用explain analyze来查看样本或生产数据在现实世界中的工作原理。

使用多列索引时,请记住,至少对于b-tree索引,Pg可以使用(a,b)上的索引来查找在aa上同时进行过滤的查询b,但不适用于仅在b上过滤的查询。索引从左到右可用,您不能使用索引来搜索索引右侧的值,除非您还搜索其左侧的所有值。