正确的全文索引Rails / PostgreSQL / pg_search

我正在测试PostgreSQL全文搜索(使用pg_search gem)和solr(sunspot_solr gem)的性能。

对于400万条记录,我获得了13456毫秒的Tsearch800毫秒的SOLR (即SOLR查询+数据库回溯)。 很明显,我需要索引,但我不知道如何创建一个全文搜索。 我调查并发现,对于全文搜索,我应该使用GIN索引。

execute "CREATE INDEX products_gin_title ON products USING GIN(to_tsvector('english', title))" 

但我正在搜索另外两列,我需要多值索引,我不知道如何实现它? 我对DB部分不是很熟悉。 我的搜索代码如下:

 @results = Product.search_title(params[:search_term]).where("platform_id=? AND product_type=?", params[:platform_id], params[:type_id]).limit(10).all 

如何为此类情况创建正确的查询?

这是来自rails的搜索词车的 SQL输出。

 Product Load (12494.0ms) SELECT "products".*, ( ts_rank((to_tsvector('simple', coalesce("products"."title"::text, ''))), (to_ tsquery('simple', ''' ' || 'car' || ' ''')), 2) ) AS pg_search_rank FROM "products" WHERE (((to_tsvector('simple', coalesce("products"."tit le"::text, ''))) @@ (to_tsquery('simple', ''' ' || 'car' || ' ''')))) AND (platform_id='26' AND product_type='2') ORDER BY pg_search_rank DESC, "products"."id" ASC LIMIT 10 

编辑:

我正在使用PostgreSQL 8.4.11, EXPLAIN ANALYZE输出如下。

 Limit (cost=108126.34..108126.36 rows=10 width=3824) (actual time=12228.736..12228.738 rows=10 loops=1) -> Sort (cost=108126.34..108163.84 rows=14999 width=3824) (actual time=12228.733..12228.734 rows=10 loops=1) Sort Key: (ts_rank(to_tsvector('simple'::regconfig, COALESCE((title)::text, ''::text)), '''car'''::tsquery, 2)), id Sort Method: top-N heapsort Memory: 18kB -> Seq Scan on products (cost=0.00..107802.22 rows=14999 width=3824) (actual time=7.532..12224.585 rows=977 loops=1) Filter: ((platform_id = 26) AND (product_type = 2) AND (to_tsvector('simple'::regconfig, COALESCE((title)::text, ''::text)) @@ '''car'''::tsquery)) Total runtime: 12228.813 ms 

这个表达式:

 to_tsvector('simple', (COALESCE(title::TEXT), '')) 

不能对你的指数进行抨击。

您应该在查询中使用的表达式上声明索引:

 CREATE INDEX products_gin_title ON products USING GIN(to_tsvector('simple', COALESCE(title::TEXT,''))) 

(或使ruby生成索引中使用的表达式)。

如果要将多列编入索引,只需将它们连接起来:

 CREATE INDEX products_gin_title ON products USING GIN(to_tsvector('simple', title || ' ' || product_type || ' ' || platform_id)) 

但同样,Ruby应该过滤完全相同的表达式,以便使用索引。