0

我一直在做索引的最后几天有些沉重的阅读和我想以正确的方式找出该索引的查询我有一个很大的制约。我正在使用postgres_ext gem来支持数组数据类型和GIN和GIST索引类型。PostgreSQL中复杂的索引类型和排序

我有两个查询

.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的在使用这两个多列索引第一个查询?

数组数据类型应该总是处于“杜松子酒”索引类型中吗?或者你也可以把它们放在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

请显示您的表定义或等效的Rails模型和PostgreSQL版本。 – 2013-03-09 00:33:43

+0

增加了额外的信息@CraigRinger – 2013-03-09 00:56:57

+0

Re数组和GIN,你可以有一个数组的b-tree索引,但对于像“array contains element”这样的操作没有用。你需要GIN,或者使用'intarray'扩展名和'GiST'索引类型来完成整数阵列,这将在写入负载下表现更好,但在读取负载下会更糟糕。 – 2013-03-09 01:21:00

回答

4

关于阵列和GIN,你可以有阵列的B树索引,但它不是操作有用像“数组包含元素”。您需要GIN或GiST,并且只有GIN作为所有数组类型的内置索引被支持。

您还可以使用整数数组将执行读取负载下写入负载下更好,但更糟糕的intarray extension和,其要旨索引类型。

作为确定PG是否会使用这两个指标,说最好的方法是使用EXPLAIN ANALYZE看看。获取语​​句Rails通过启用log_statement或从SQL日志记录的Rails日志启动PostgreSQL日志。然后在psqlexplain analyze运行它。或者,使用auto_explain extension在查询运行时捕获性能报告。

我有,你会发现,PG不能结合梗概或GIN并在同一个过滤器B树索引的感觉。组合索引需要位图索引扫描,而这个IIRC只适用于两个b-tree索引。您可能需要将额外的列添加到GiST或GIN索引,但这会大大增加索引大小,可能不值得。

你真的需要使用explain analyze,看看它是如何工作在现实世界中的样品或生产数据。

当使用多列索引时,请记住,至少在B树索引PG可以a或两个ab,但不能用于查询该过滤器只在b(a,b)使用索引的查询的过滤器。索引可以从左到右使用,除非您还在左侧搜索所有值,否则不能使用索引搜索索引右侧的值。

+0

非常感谢您的回答Craig,一个跟进问题。你说你可以在b-tree索引中有数组,但不能用于“包含”操作,你可以使用什么操作? “=”? – 2013-03-09 18:27:14

+0

@KyleC B树索引支持'=','<>'(不等于),'>','<', '> ='和'<=',即相等和简单的排序。对排序的支持意味着它们可以用于'BETWEEN'和前缀搜索,比如'LIKE'abcd%'',但不适用于LIKE'%ab%'或数组''>(包含)'的中缀搜索。更多细节可以在PostgreSQL文档中找到。 – 2013-03-10 01:28:55