【问题标题】:Speed up fulltext search - pgsql加速全文搜索 - pgsql
【发布时间】:2017-03-03 04:07:05
【问题描述】:

根据使用全文搜索加速 postgresql 查询,我看到了数百万个线程。我试图做所有事情,但没有更多的想法。 我有相当大的(此时有 20 612 971 条记录)表并使用 pgsql 的全文 serach 在其中搜索,然后按 ts_rank_cd 排序。我达到了大约 3500-4000 毫秒来执行查询。有什么想法可以让它更快吗?如果可能的话,我不想使用像 sphinx 或 solr 这样的外部软件。因此,首选本地 postgresql 解决方案 :) 下面是对我的表的描述和解释分析选择的示例。

# \d artifacts.item
                                           Table "artifacts.item"
     Column          |            Type             |                          Modifiers                          
-------------------------+-----------------------------+-------------------------------------------------------------
 add_timestamp           | timestamp without time zone | 
 author_account_id       | integer                     | 
 description             | text                        | 
 id                      | integer                     | not null default nextval('artifacts.item_id_seq'::regclass)
 removed_since_timestamp | timestamp without time zone | 
 slug                    | character varying(2044)     | not null
 thumb_height            | integer                     | 
 thumb_path              | character varying(2044)     | default NULL::character varying
 thumb_width             | integer                     | 
 title                   | character varying(2044)     | not null
 search_data             | tsvector                    | 
 tags                    | integer[]                   | 
 is_age_restricted       | boolean                     | not null default false
 is_on_homepage          | boolean                     | not null default false
 is_public               | boolean                     | not null default false
 thumb_filename          | character varying(2044)     | 
 is_removed              | boolean                     | not null default false
Indexes:
    "artifacts_item_add_timestamp_idx" btree (add_timestamp DESC NULLS LAST)
    "artifacts_item_id_idx" btree (id)
    "artifacts_item_is_on_homepage_add_timestamp" btree (is_on_homepage DESC, add_timestamp DESC NULLS LAST)
    "artifacts_item_is_on_homepage_idx" btree (is_on_homepage)
    "artifacts_item_search_results" gin (search_data) WHERE is_public IS TRUE AND is_removed IS FALSE
    "artifacts_item_tags_gin_idx" gin (tags)
    "artifacts_item_thumbs_list" btree (is_public, is_removed, id DESC)
    "index1" btree (add_timestamp)
    "itemIdx" btree (is_public, is_removed, is_age_restricted)
    "item_author_account_id_idx" btree (author_account_id)

分析:

# explain analyze SELECT i.id, 
#     i.title, 
#     i.description, 
#     i.slug, 
#     i.thumb_path, 
#     i.thumb_filename, 
#     CONCAT(
#         i.thumb_path, 
#         '/', 
#         i.thumb_filename
#     ) AS thumb_url, 
#     (CASE WHEN i.thumb_width = 0 THEN 280 ELSE i.thumb_width END) as thumb_width, 
#     (CASE WHEN i.thumb_height = 0 THEN 280 ELSE i.thumb_height END) as thumb_height, 
#     (i.thumb_height > i.thumb_width) AS is_vertical, 
#     i.add_timestamp 
# FROM artifacts.item AS i 
# WHERE i.is_public IS true 
#     AND i.is_removed IS false 
#     AND (i.search_data @@ to_tsquery('public.polish', $$'lego'$$)) 
# ORDER BY ts_rank_cd(i.search_data, to_tsquery('public.polish', $$'lego'$$)) desc, 
#     ts_rank_cd(i.search_data, to_tsquery('public.polish', $$'lego'$$)) desc, 
#     i.add_timestamp DESC NULLS LAST  
# LIMIT 60
# OFFSET 0;
                                                                           QUERY PLAN                                                                           
----------------------------------------------------------------------------------------------------------------------------------------------------------------
 Limit  (cost=358061.78..358061.93 rows=60 width=315) (actual time=335.870..335.876 rows=60 loops=1)
   ->  Sort  (cost=358061.78..358357.25 rows=118189 width=315) (actual time=335.868..335.868 rows=60 loops=1)
         Sort Key: (ts_rank_cd(search_data, '''lego'' | ''lega'''::tsquery)), add_timestamp
         Sort Method: top-N heapsort  Memory: 55kB
         ->  Bitmap Heap Scan on item i  (cost=2535.96..353980.19 rows=118189 width=315) (actual time=33.163..308.371 rows=62025 loops=1)
               Recheck Cond: ((search_data @@ '''lego'' | ''lega'''::tsquery) AND (is_public IS TRUE) AND (is_removed IS FALSE))
               ->  Bitmap Index Scan on artifacts_item_search_results  (cost=0.00..2506.42 rows=118189 width=0) (actual time=23.066..23.066 rows=62085 loops=1)
                     Index Cond: (search_data @@ '''lego'' | ''lega'''::tsquery)
 Total runtime: 335.967 ms
(9 rows)

Time: 3444.731 ms

【问题讨论】:

    标签: postgresql


    【解决方案1】:

    符合条件的行有 62025 行,必须排序……
    这需要一段时间。您是否有可能拥有整个数据库或至少 RAM 中的索引?这会有所帮助。

    【讨论】:

    • 那个 db 重量是 80GB :) 我在主板上没有那么多内存插槽 :) 你指的是哪个索引?
    • 索引为artifacts_item_search_results,但您也需要内存中的表。如果您使用pg_prewarm 将其放入缓存中,这可能会有所帮助。但如果您不一直使用它,它可能会再次从缓存中退出。现在 80GB RAM 已经不算多 - 考虑买一台更大的机器。
    • 好的,所以也许是关于外部解决方案。索尔?狮身人面像?也许还有别的?
    • 然后 - 所以 - 没有更多的优化方法了?
    • 据我所知,这与 PostgreSQL 中的速度一样快。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-16
    • 2018-09-22
    • 2021-10-24
    • 1970-01-01
    • 2018-10-12
    • 1970-01-01
    • 2013-06-24
    相关资源
    最近更新 更多