Postgres запрос иногда занимает очень много времени - PullRequest
1 голос
/ 03 августа 2020

Я реализовал движок FTS на своем веб-сайте, используя GIN tsvector, и он работает довольно хорошо, но в некоторых случаях это занимает очень много времени без какой-либо конкретной c причины. Я копирую вывод команды EXPLAIN ANALYE ниже:

sitedb=# EXPLAIN ANALYZE SELECT id, title FROM post_1 WHERE search_vector @@   to_tsquery('quantum');
                                                      QUERY PLAN                                                           
-------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on post_1  (cost=315.68..105654.80 rows=32443 width=106) (actual   time=76.963..17281.184 rows=31925 loops=1)
   Recheck Cond: (search_vector @@ to_tsquery('quantum'::text))
   Heap Blocks: exact=29259
   ->  Bitmap Index Scan on index1_idx  (cost=0.00..307.57 rows=32443 width=0) (actual time=60.208..60.209 rows=31925 loops=1)
     Index Cond: (search_vector @@ to_tsquery('quantum'::text))
 Planning Time: 47.648 ms
 Execution Time: 17308.511 ms
(7 rows)

В какой-то момент я подумал, что изменение work_mem поможет. Я установил для него 86 МБ, и он остался прежним.

Странно то, что если я повторно запустил ту же команду сразу после этого, это будет намного быстрее. См. Ниже:

sitedb=# EXPLAIN ANALYZE SELECT id, title FROM post_1 WHERE search_vector @@ to_tsquery('quantum');
                                                      QUERY PLAN                                                           
-------------------------------------------------------------------------------------------------------------------------------
 Bitmap Heap Scan on post_1  (cost=315.68..105654.80 rows=32443 width=106) (actual time=44.542..495.525 rows=31925 loops=1)
   Recheck Cond: (search_vector @@ to_tsquery('quantum'::text))
   Heap Blocks: exact=29259
   ->  Bitmap Index Scan on index1_idx  (cost=0.00..307.57 rows=32443 width=0) (actual time=29.256..29.256 rows=31925 loops=1)
     Index Cond: (search_vector @@ to_tsquery('quantum'::text))
 Planning Time: 0.597 ms
 Execution Time: 502.296 ms
(7 rows)

Есть ли у кого-нибудь идея?

Большое спасибо.

1 Ответ

1 голос
/ 04 августа 2020

Это наверное холодный кеш. Например, он должен был прочитать 29 259 страниц, и некоторые из них уже были в памяти. При втором запуске они находятся в памяти, поэтому работает быстрее. Вы можете помочь подтвердить это, выполнив EXPLAIN (ANALYZE, BUFFERS) после включения track_io_timing.

Вы можете увеличить effective_io_concurrency так, чтобы PostgreSQL имел несколько невыполненных запросов ввода-вывода одновременно. Насколько это эффективно, будет зависеть от вашего оборудования ввода-вывода. Это должно быть более эффективным, например, на чередующемся RAID или JBOD.

Если ваш кеш был холодным из-за недавнего перезапуска, не перезагружайте его очень часто или используйте pg_prewarm для разогрева кеша, когда вы это делаете . Если он не может оставаться в кеше, потому что ваши часто используемые данные слишком велики, чтобы они могли оставаться в памяти, тогда получите больше ОЗУ или получите более быстрые диски (например, SSD, или если они уже являются SSD, приобретите более качественные).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...