¿Por qué no se usa mi índice de matriz PostgreSQL (Rails 4)?

Tengo una matriz de cadenas PostgreSQL como columna en una tabla. Creé un índice usando el método GIN. Pero CUALQUIER pregunta no usará el índice (en su lugar, están haciendo un escaneo secuencial de toda la tabla con un filter). ¿Qué me estoy perdiendo?

Aquí está mi migration:

class CreateDocuments < ActiveRecord::Migration def up create_table :documents do |t| t.string :title t.string :tags, array: true, default: [] t.timestamps end add_index :documents, :tags, using: 'gin' (1..100000).each do |i| tags = [] tags << 'even' if (i % 2) == 0 tags << 'odd' if (i % 2) == 1 tags << 'divisible by 3' if (i % 3) == 0 tags << 'divisible by 4' if (i % 4) == 0 tags << 'divisible by 5' if (i % 5) == 0 Document.create( title: i, tags: tags ) end end def down drop_table :documents end end 

Aquí está mi consulta, con el número resultante de filas.

 Document.where("'divisible by 5' = ANY (tags)").explain Document Load (249.8ms) SELECT "documents".* FROM "documents" WHERE ('divisible by 5' = ANY (tags)) D, [2014-03-07T17:09:49.689709 #41937] DEBUG -- : Document Load (249.8ms) SELECT "documents".* FROM "documents" WHERE ('divisible by 5' = ANY (tags)) => EXPLAIN for: SELECT "documents".* FROM "documents" WHERE ('divisible by 5' = ANY (tags)) QUERY PLAN ----------------------------------------------------------------- Seq Scan on documents (cost=0.00..3500.00 rows=20057 width=69) Filter: ('divisible by 5'::text = ANY ((tags)::text[])) (2 rows) Document.where("'divisible by 5' = ANY (tags)").length Document Load (258.0ms) SELECT "documents".* FROM "documents" WHERE ('divisible by 5' = ANY (tags)) D, [2014-03-07T17:09:55.536517 #41937] DEBUG -- : Document Load (258.0ms) SELECT "documents".* FROM "documents" WHERE ('divisible by 5' = ANY (tags)) => 20000 

Para trabajar con un índice GIN use el operador <@ ("está contenido por") en lugar de la construcción ANY .

El manual establece aquí que los índices de GIN pnetworkingeterminados actualmente solo son compatibles con estos operadores (la funcionalidad adicional se envía con extensiones):

 <@ @> = && 

Por lo tanto, intente esta consulta:

 Document.where("'{divisible by 5}' <@ tags").explain 

Tenga en count que el lado izquierdo también debe estar en la array notation , incluso si se trata de un elemento único. El operador <@ funciona para arreglos . De ahí '{divisible by 5}' .