当WHERE子句中有OR时,如何编写复合索引?

时间:2012-11-20 08:22:03

标签: ruby-on-rails postgresql

我想添加一个复合索引来加速以下查询:

User.where("name = 'bob' AND (x IS TRUE OR y = 'foo' OR z = 'bar') AND image_url <> ''")

如何说明xyz

我尝试添加一个这样的索引:

# rails migration file
add_index :users, [ :name, :x, :y, :z, :image_url ], name: "index_users_on_blah"

但它似乎没有做任何事情......或者至少在我EXPLAIN时我没有发现任何差异。

2 个答案:

答案 0 :(得分:1)

部分索引可能会更好,列应该有不同的顺序:

create index index_users_on_blah on users (name, x, y, z) where image_url <> ''

不确定Rails是否支持'部分索引',但您应该重新安排索引列:

create index index_users_on_blah on users (name, image_url, x, y, z) where image_url <> ''

你应该读到这个:

答案 1 :(得分:0)

如果这是您感兴趣的唯一一组条件,您可以尝试创建索引:

 create index index_name
 on table_name (
   name,
   case when x IS TRUE OR y = 'foo' OR z = 'bar'
        then true
        else false
   end)

...并将您的查询重写为:

 name = 'Bob' and
 case when x IS TRUE OR y = 'foo' OR z = 'bar'
      then true
      else false
 end

我不确定PostgreSQL查询优化器对空格的敏感程度,但首先要考虑它。

缺点是,如果你想要相同的查询但x是假的,它就不是很灵活。