powered by simpleCommunicator - 2.0.40     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Странное поведение gin индекса
4 сообщений из 4, страница 1 из 1
Странное поведение gin индекса
    #40124290
andrei07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем привет
Есть PostgreSQL 13.1 (Debian 13.1-1.pgdg100+1) on x86_64-pc-linux-gnu, compiled by gcc (Debian 8.3.0-6) 8.3.0, 64-bit

Есть для меня крайне странная ситуация при НЕ использовании индексов.
Запрос 1
Код: sql
1.
2.
3.
4.
select * 
from doc d
where d.tags @> (string_to_array( :tags,',' ))
limit 500;



Где tags - text[] и создан gin индекс (array_ops).
Если ввожу массив с частотным данным - идет seq scan.
Если ввожу массив с не частотными данными - используется индекс.
Вроде все логично.

План
Код: sql
1.
2.
3.
4.
5.
6.
Limit  (cost=0.00..92.52 rows=500 width=1322) (actual time=0.131..279.214 rows=500 loops=1)
  ->  Seq Scan on doc d  (cost=0.00..58035.04 rows=313648 width=1322) (actual time=0.130..278.882 rows=500 loops=1)
        Filter: (tags @> '{слово}'::text[])
        Rows Removed by Filter: 1
Planning Time: 0.279 ms
Execution Time: 279.381 ms




Проблема 1.
Если переписать запрос
Запрос 2
Код: sql
1.
2.
3.
4.
select * 
from doc d
where d.tags @> array(select value from jsonb_array_elements_text (:tags))
limit 500


Где tags будет json массивом, то индекс будет использоваться ВСЕГДА.

План
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
Limit  (cost=57.17..1785.24 rows=500 width=1322) (actual time=38.573..39.290 rows=500 loops=1)
  InitPlan 1 (returns $0)
    ->  Function Scan on jsonb_array_elements_text  (cost=0.00..1.00 rows=100 width=32) (actual time=0.019..0.020 rows=1 loops=1)
  ->  Bitmap Heap Scan on doc d  (cost=56.17..5482.30 rows=1570 width=1322) (actual time=38.571..39.239 rows=500 loops=1)
        Recheck Cond: (tags @> $0)
        Heap Blocks: exact=96
        ->  Bitmap Index Scan on doc_i4  (cost=0.00..55.78 rows=1570 width=0) (actual time=29.929..29.930 rows=314049 loops=1)
              Index Cond: (tags @> $0)
Planning Time: 0.278 ms
Execution Time: 39.378 ms



Почему так происходит?
Фактически наблюдаю проблему, что по частотным тегам использование индекса лучше и запрос выполняется быстрее.

Проблема 2.
Если в первом варианте запроса со string_to_array применить какие-то еще условия в where, то индексы для них вообще не используются (и выполнение запроса занимает вплоть до 10 секунд). А для второго - всегда используются (время запроса - около 1s). Могу тут тоже представить планы, но для 1 запрос там остается обычный seq scan, для второго все корректно - все индексы используются.

Почему не используются индексы для первого запроса?
...
Рейтинг: 0 / 0
Странное поведение gin индекса
    #40125445
andrei07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Идеи?
...
Рейтинг: 0 / 0
Странное поведение gin индекса
    #40125450
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
andrei07
Идеи?


1)сделайте для теста
set enable_seq_scan to 0;
и заново explain analyze исходного запроса...

надо сравнить цену (cost) с точки зрения базы для seq scan и bitmap scan

и если цена отличается от реальных времязатрат - думать о том что и как в *_cost параметрах у вас в настройках базы не соответствует реальности.

--
Maxim Boguk
лучшая поддержка PostgreSQL: dataegret.ru
...
Рейтинг: 0 / 0
Странное поведение gin индекса
    #40126080
andrei07
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Maxim Boguk,
В таблице немного данные поменялись, поэтому заново приведу исходный план

set enable_seqscan = on;
plan:
Код: plsql
1.
2.
3.
4.
5.
Limit  (cost=0.00..92.49 rows=500 width=1318) (actual time=0.175..284.375 rows=500 loops=1)
  ->  Seq Scan on doc d  (cost=0.00..58035.59 rows=313728 width=1318) (actual time=0.174..284.062 rows=500 loops=1)
        Filter: (tags @> '{слово}'::text[])
Planning Time: 0.277 ms
Execution Time: 284.586 ms




set enable_seqscan = off;
plan:
Код: plsql
1.
2.
3.
4.
5.
6.
7.
8.
Limit  (cost=2939.39..3031.88 rows=500 width=1318) (actual time=41.426..42.726 rows=500 loops=1)
  ->  Bitmap Heap Scan on doc d  (cost=2939.39..60970.99 rows=313728 width=1318) (actual time=41.424..42.678 rows=500 loops=1)
        Recheck Cond: (tags @> '{слово}'::text[])
        Heap Blocks: exact=91
        ->  Bitmap Index Scan on doc_i4  (cost=0.00..2860.96 rows=313728 width=0) (actual time=32.020..32.020 rows=314049 loops=1)
              Index Cond: (tags @> '{слово}'::text[])
Planning Time: 0.288 ms
Execution Time: 42.786 ms



Т.е. cost=0.00..2860.96, а у исходного cost=0.00..58035.59. Т.е. вывод, что все же планировщик должен был выбрать сканирование по индексу?

По *_cost параметрам - никаких изменений не вносилось, все стоит дефолтное.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Странное поведение gin индекса
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]