【问题标题】:PostgreSQL Complex indexing types and orderingPostgreSQL 复杂的索引类型和排序
【发布时间】:2013-03-08 19:56:31
【问题描述】:

在过去的几天里,我一直在阅读有关索引的大量信息,我正在尝试找出正确的方法来索引我有很多限制的查询。我正在使用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-tree 索引中?

最后会在两个查询中将第一个索引用于“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

【问题讨论】:

  • 请显示您的表定义或等效的 Rails 模型和 PostgreSQL 版本。
  • 添加了更多信息@CraigRinger
  • 重新数组和 GIN,您可以拥有数组的 b-tree 索引,但它对于“数组包含元素”之类的操作没有用。为此,您需要 GIN,或者将 intarray 扩展及其 GiST 索引类型用于整数数组,在写入负载下性能更好,但在读取负载下性能更差。
  • 感谢您的回复。还有一个问题,第一个查询会使用两个索引吗?
  • 最好的判断方法是使用EXPLAIN ANALYZE 看看。

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


【解决方案1】:

关于数组和 GIN,您可以拥有数组的 b-tree 索引,但它对于“数组包含元素”之类的操作没有用处。为此,您需要 GIN 或 GiST,并且仅支持将 GIN 作为所有数组类型的内置索引。

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

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

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

您确实需要使用explain analyze 来了解它在现实世界中如何处理样品或生产数据。

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

【讨论】:

  • 非常感谢克雷格的回答,一个后续问题。你说你可以在 b-tree 索引中有数组,但不能用于“包含”操作,你可以使用哪些操作? "=" ?
  • @KyleC B-tree 索引支持=<>(不等于)、><>=<=,即相等和简单排序。支持排序意味着它们可以用于BETWEENLIKE 'abcd%' 之类的前缀搜索,但不能用于LIKE '%ab%' 之类的中缀搜索或数组@>(包含)。更多细节可以在 PostgreSQL 文档中找到。
猜你喜欢
  • 1970-01-01
  • 2021-08-22
  • 2021-01-02
  • 2011-05-02
  • 2023-03-11
  • 1970-01-01
  • 2016-12-29
  • 1970-01-01
  • 2015-12-08
相关资源
最近更新 更多