在过去的几天里,我一直在做索引的重读,我正试图找出正确的方法来索引我有很多约束的查询。我使用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
答案 0 :(得分:4)
关于数组和GIN,您可以拥有数组的b树索引,但它对“array contains element”之类的操作没有用。您需要GIN或GiST,并且只支持GIN作为所有数组类型的内置索引。
您还可以将intarray
extension及其GiST索引类型用于整数数组,这些数组在写入负载下性能会更好,但在读取负载下会更差。
至于确定Pg是否会使用两个索引,最好的方法是使用EXPLAIN ANALYZE
并查看。通过启用log_statement
或从带有SQL登录的Rails日志获取Rails在PostgreSQL日志中执行的语句。然后使用psql
在explain analyze
中运行它。或者,使用auto_explain
extension在运行时捕获有关查询的性能报告。
我觉得你会发现Pg无法在同一个过滤器中组合GiST或GIN和b树索引。组合索引需要位图索引扫描,而IIRC仅适用于两个b树索引。您可能需要将额外的列添加到GiST或GIN索引,但这会极大地增加索引大小,可能不值得。
您确实需要使用explain analyze
来查看样本或生产数据在现实世界中的工作原理。
使用多列索引时,请记住,至少对于b-tree索引,Pg可以使用(a,b)
上的索引来查找在a
或a
上同时进行过滤的查询b
,但不适用于仅在b
上过滤的查询。索引从左到右可用,您不能使用索引来搜索索引右侧的值,除非您还搜索其左侧的所有值。