2014-03-07 31 views
1

我有一個PostgreSQL字符串數組作爲表中的列。我使用GIN方法創建了一個索引。但是,任何查詢都不會使用索引(而是使用過濾器對整個表進行順序掃描)。我錯過了什麼?爲什麼我的PostgreSQL數組索引無法使用(Rails 4)?

這裏是我的移民:

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 

這裏是我的查詢,用得到的行數。

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 
+0

「產品」表有多少行? –

+0

該列的基數是什麼?多少個唯一記錄報告給行數? – Mihai

+0

@IgorRomanchenko該表有超過100,000行 – mohith

回答

2

若要使用GIN索引使用<@ ("is contained by") operator而不是ANY construct的。

The manual states here是默認GIN指標目前僅支持這些操作符(附加功能附帶擴展):

<@ 
@> 
= 
&& 

因此,嘗試此查詢:

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

注意左邊需要也在array notation,即使它是一個單一的元素。運營商<@適用於陣列。因此'{divisible by 5}'

+0

輝煌。謝謝! – mohith

相關問題