Я использую 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 минуты для бега ???