PostgreSql фразуto_tsquery очень медленно - PullRequest
0 голосов
/ 05 июня 2019

Я использую PostgreSql 9,6

У меня есть таблица базы данных с примерно 16 миллионами записей.У меня есть столбец jsonb - logentry, который имеет поле с именем «message».Он имеет индекс GIN, созданный следующим образом:

CREATE INDEX inettklog_ix_ts_message
    ON public.inettklog USING gin
    (to_tsvector('english'::regconfig, logentry ->> 'message'::text))
    TABLESPACE pg_default;

Я хочу выполнить поиск по «имени приложения».

Запрос с предложением WHERE

 to_tsvector('english', logentry->>'message') @@ plainto_tsquery('application name') 

выполняется за 113 мсек и возвращает 7349 строк

ОБЪЯСНИТЬ АНАЛИЗ:

 WindowAgg  (cost=1812.98..2240.22 rows=95 width=12) (actual time=84.037..84.986 rows=7315 loops=1)
   ->  Bitmap Heap Scan on inettklog  (cost=1812.98..2239.03 rows=95 width=4) (actual time=17.943..81.708 rows=7315 loops=1)
         Recheck Cond: (to_tsvector('english'::regconfig, (logentry ->> 'message'::text)) @@ plainto_tsquery('application name'::text))
         Heap Blocks: exact=7574
         ->  Bitmap Index Scan on inettklog_ix_ts_message  (cost=0.00..1812.96 rows=95 width=0) (actual time=8.542..8.542 rows=8009 loops=1)
               Index Cond: (to_tsvector('english'::regconfig, (logentry ->> 'message'::text)) @@ plainto_tsquery('application name'::text))
 Planning time: 0.387 ms
 Execution time: 85.243 ms

Но я не хочу "приложение" и "имя", я хочу "имя приложения"

Но запрос с предложением WHERE, равным

 to_tsvector('english', logentry->>'message') @@ phraseto_tsquery('application name') 

, выполняется более 2 минут!

ОБЪЯСНИТЕ АНАЛИЗ:

 WindowAgg  (cost=852.98..1280.22 rows=95 width=12) (actual time=145065.204..145066.127 rows=7314 loops=1)
   ->  Bitmap Heap Scan on inettklog  (cost=852.98..1279.03 rows=95 width=4) (actual time=55.180..145030.148 rows=7314 loops=1)
         Recheck Cond: (to_tsvector('english'::regconfig, (logentry ->> 'message'::text)) @@ phraseto_tsquery('application name'::text))
         Heap Blocks: exact=7573
         ->  Bitmap Index Scan on inettklog_ix_ts_message  (cost=0.00..852.96 rows=95 width=0) (actual time=8.196..8.196 rows=8008 loops=1)
               Index Cond: (to_tsvector('english'::regconfig, (logentry ->> 'message'::text)) @@ phraseto_tsquery('application name'::text))
 Planning time: 25.926 ms
 Execution time: 145067.052 ms

Конечно, "<-> "оператор работает, сначала находя строки, содержащие" application "и" name ", а затем фильтрует результат, чтобы найти те строки, в которых" name "следует за" application ".

И, если да, то почему2 минуты для бега ???

1 Ответ

0 голосов
/ 06 июня 2019

Индекс GIN, к сожалению, не может поддерживать упорядочение лексем. Ваш первый запрос намного быстрее, потому что он может обрабатывать все, используя созданный вами индекс. С версией фразы, перепроверка должна фактически пойти к вашей таблице и создать ts_vectors, чтобы найти порядок.

Вы можете использовать индекс RUM: https://github.com/postgrespro/rum, который включает в себя информацию для заказа.

Эта статья значительно расширяет эти вопросы.

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