Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/postgresql/10.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ruby on rails 正确的全文索引Rails/PostgreSQL/pgu搜索_Ruby On Rails_Postgresql_Pg Search - Fatal编程技术网

Ruby on rails 正确的全文索引Rails/PostgreSQL/pgu搜索

Ruby on rails 正确的全文索引Rails/PostgreSQL/pgu搜索,ruby-on-rails,postgresql,pg-search,Ruby On Rails,Postgresql,Pg Search,我正在测试PostgreSQL全文搜索(使用pg_search gem)和solr(sunspot_solr gem)的性能 对于400万条记录,我得到了13456毫秒的Tsearch和800毫秒的SOLR(即SOLR query+DB Retrieval)。很明显,我需要索引,但我不知道如何为全文搜索创建索引。我调查发现,对于全文搜索,我应该使用GIN索引 execute "CREATE INDEX products_gin_title ON products USING GIN(to_tsv

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

对于400万条记录,我得到了13456毫秒的Tsearch800毫秒的SOLR(即SOLR query+DB Retrieval)。很明显,我需要索引,但我不知道如何为全文搜索创建索引。我调查发现,对于全文搜索,我应该使用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对搜索词car的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应该在完全相同的表达式上进行过滤,以便使用索引。

请在发布的查询上发布运行
EXPLAIN ANALYZE
的输出,以及您的Pg版本、您更改的任何postgresql.conf参数等。感谢您第一次使用单列索引,现在查询时间是80毫秒,很好!除此之外,您的问题是,是否应该使用多列索引来进一步提高速度?当你说连接它们时,这是否意味着我应该通过将FK id连接到我的搜索词来进行全文搜索?在本例中,我通过全文搜索标题,并使用产品类型、平台id(提到FKs)缩小结果范围。我的印象是,如果您想加快特定查询的速度,您需要为该查询中使用的所有列添加索引。@Dolphin:您不能创建复合
GIN
索引。可以,但这是一项非常复杂的任务,需要创建自定义运算符类和其他暗魔法。这还需要
SUPER
权限(这意味着你不能在托管数据库上执行此操作),这将我的搜索时间从3000毫秒缩短到60毫秒。非常感谢。