Частотный счетчик фраз с ПОЛНЫМ текстовым поиском PostgreSQL 9,6 - PullRequest
0 голосов
/ 17 января 2020

Мне нужно вычислить количество раз, когда фраза появляется, используя ts_query для индексированного текстового поля (ts_vector тип данных). Это работает, но это очень медленно, потому что таблица огромна. Для отдельных слов я предварительно рассчитал все частоты, но у меня нет идей по увеличению скорости поиска по фразе.

Редактировать: Спасибо за ваш ответ @ jjanes.

Это мой запрос :

SELECT substring(date_input::text,0,5) as myear, ts_headline('simple',text_input,q, 'StartSel=<b>, StopSel=</b>,MaxWords=2, MinWords=1, ShortWord=1, HighlightAll=FALSE, MaxFragments=9999, FragmentDelimiter=" ... "') as headline 
FROM 
db_test, to_tsquery('simple','united<->kingdom') as q WHERE date_input BETWEEN '2000-01-01'::DATE AND '2019-12-31'::DATE and idxfti_simple @@ q 

И это вывод EXPLAIN (ANALYZE, BUFFERS):

Nested Loop  (cost=25408.33..47901.67 rows=5509 width=64) (actual time=286.536..17133.343 rows=38127 loops=1)
Buffers: shared hit=224723
    ->  Function Scan on q  (cost=0.00..0.01 rows=1 width=32) (actual time=0.005..0.007 rows=1 loops=1)
    ->  Append  (cost=25408.33..46428.00 rows=5510 width=625) (actual time=285.372..864.868 rows=38127 loops=1)
        Buffers: shared hit=165713
        ->  Bitmap Heap Scan on db_test  (cost=25408.33..46309.01 rows=5509 width=625) (actual time=285.368..791.111 rows=38127 loops=1)
            Recheck Cond: ((idxfti_simple @@ q.q) AND (date_input >= '2000-01-01'::date) AND (date_input <= '2019-12-31'::date))
            Rows Removed by Index Recheck: 136
            Heap Blocks: exact=29643
            Buffers: shared hit=165607
                ->  BitmapAnd  (cost=25408.33..25408.33 rows=5509 width=0) (actual time=278.370..278.371 rows=0 loops=1)
                Buffers: shared hit=3838
                    ->  Bitmap Index Scan on idxftisimple_idx  (cost=0.00..1989.01 rows=35869 width=0) (actual time=67.280..67.281 rows=176654 loops=1)
                        Index Cond: (idxfti_simple @@ q.q)
                        Buffers: shared hit=611
                    ->  Bitmap Index Scan on db_test_date_input_idx  (cost=0.00..23142.24 rows=1101781 width=0) (actual time=174.711..174.712 rows=1149456 loops=1)
                        Index Cond: ((date_input >= '2000-01-01'::date) AND (date_input <= '2019-12-31'::date))
                        Buffers: shared hit=3227
        ->  Seq Scan on test  (cost=0.00..118.98 rows=1 width=451) (actual time=0.280..0.280 rows=0 loops=1)
            Filter: ((date_input >= '2000-01-01'::date) AND (date_input <= '2019-12-31'::date) AND (idxfti_simple @@ q.q))
            Rows Removed by Filter: 742
            Buffers: shared hit=106

Planning time: 0.332 ms
Execution time: 17176.805 ms

Извините, я не могу включить track_io_timing. Я знаю, что ts_headline не рекомендуется, но мне нужно вычислить, сколько раз фраза появляется в одном и том же поле.

Заранее благодарю за помощь.

Ответы [ 2 ]

1 голос
/ 20 января 2020

Обратите внимание, что выборка строк в Bitmap Heap Scan выполняется довольно быстро, <0,8 секунды, и почти все время проводится в узле верхнего уровня. Это время, вероятно, будет потрачено в ts_headline, при повторном анализе документа text_input. Пока вы продолжаете использовать ts_headline, вы ничего не можете с этим поделать. </p>

ts_headline напрямую не дает вам то, что вы хотите (частоту), поэтому вы должны выполнять какую-то постобработку этого Возможно, вы могли бы перейти непосредственно к постобработке tsvector, чтобы документ не нужно было повторно анализировать.

Другой вариант - это дальнейшее обновление, которое может позволить распространить работу ts_headline на несколько процессоров. PostgreSQL 9.6 была первой версией, которая поддерживала параллельный запрос, и в этой версии она была недостаточно зрелой, чтобы можно было распараллеливать подобные вещи. v10, вероятно, достаточно, чтобы получить параллельный запрос для этого, но вы также можете перейти к v12.

1 голос
/ 18 января 2020

Версия 9.2 старая и больше не поддерживается. Во-первых, у него не было встроенной поддержки поиска фраз (введено в 9.6).

Пожалуйста, обновите.

А если он все еще медленный, покажите нам запрос и EXPLAIN (ANALYZE, BUFFERS) для него, желательно с включенным track_io_timing.

...