SQL запросы стали тормозить

Использую СУБД Postgresql, относительно не так давно, SQL запросы стали выполняться намного дольше по времени. Некоторые запросы выполняются в несколько десятков раз дольше.
Провел анализ работы БД (сравнил с данными месячной давности), проблем с памятью или процами нет. Но заметил что время доступа к разделу с БД различается на порядок, что можно с эти сделать, кроме банального VACUUM FULL ANALYZE?

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Вам следует вначале

Вам следует вначале посмотреть на то, как и какие именно выполняются запросы. Затем их прогнать explain'ом

SELECT total_time/calls,(total_time/1000/60)::int, * 
FROM pg_stat_statements 
ORDER BY total_time/calls DESC
LIMIT 100

В запросе стал использоваться другой индекс

В запросе стал использоваться другой индекс, правильно ли я понимаю, после
VACUUM FULL ANALYZE должна обновиться статистика, которую использует планировщик для выбора оптимального
способа выполнения запроса, также должен помочь REINDEX?
Есть ли еще способ кроме VACUUM FULL ANALYZE поставить "на путь истинный" планировщик?

К сожалению VACUUM и REINDEX

К сожалению VACUUM и REINDEX не помогли.
Как работает планировщик POSTGRES, для меня загадка.
Есть такая же БД(тестовая, с аналогичным набором данных) на другом сервере, в аналогичных запросах,
там используется нужный индекс, который раньше использовался на проблемной базе.
Приведу элементарный запрос и планы выполнения

SELECT Filed1
FROM Table1
WHERE Field2 LIKE '01%' AND Field3 = 123

План запроса на проблемной БД:

"Unique  (cost=0.43..6.21 rows=1 width=8) (actual time=1.323..11.502 rows=184 loops=1)"
"  Buffers: shared hit=4806 read=416"
"  ->  Index Scan using "Index1" on "Table1"  (cost=0.43..6.20 rows=1 width=8) (actual time=1.320..11.473 rows=184 loops=1)"
"        Index Cond: ("Filed3" = 123)"
"        Filter: ("Field2" ~~ '01%'::text)"
"        Rows Removed by Filter: 37833"
"        Buffers: shared hit=4806 read=416"
"Planning time: 26.205 ms"
"Execution time: 11.571 ms"

Используется Index1 по полю Field2 с классом оператора varchar_pattern_ops, запрос выполнялся 25 секунд

С аналогичной БД на другом сервере

"Index Scan using "Index2" on "Table1"  (cost=0.69..8.71 rows=1 width=8) (actual time=0.052..0.426 rows=184 loops=1)"
"  Index Cond: (("Filed3" = 123) AND ("Field2" ~>=~ '01'::text) AND ("Field2" ~<~ '02'::text))"
"  Filter: ("Filed2" ~~ '01%'::text)"
"  Buffers: shared hit=189"
"Planning time: 0.558 ms"
"Execution time: 0.546 ms"

Используется Index2 по полям (Field2 с классом оператора varchar_pattern_ops, Field3), запрос выполнялся 50 миллисекунд

Как-то оптимизировать запрос нельзя, куда уж проще. У меня осталась последняя мысль, удалить Index1,
но будет ли во всех местах, где действительно нужен Index1, использоваться Index2 и не будет ли он тормозить эти запросы?
Буду рад любым конструктивным идеям

Как можно скрыть оп

Как можно скрыть оп планировщика поле Field2, чтобы использовался индекс по Fileld3. В запросе

SELECT Filed1
FROM Table1
WHERE Field2 LIKE '01%' AND Fileld3 = 123

В поле Field2 в нижнем регистре тип данных text
Вариант 1:

SELECT Filed1
FROM Table1
WHERE LOWER(Field2) LIKE '01%' AND Fileld3 = 123

Вариант 2:

SELECT Filed1
FROM Table1
WHERE  (Field2 LIKE '01%')::integer=1 AND Fileld3 = 123

Может есть варианты более оптимальные?

помогли следующие волшебные

помогли следующие волшебные команды

ALTER TABLE "Table1" ALTER COLUMN "Field2" SET STATISTICS 10000;
VACUUM ANALYZE "Table1";

Опции просмотра комментариев

Выберите предпочитаемый вами способ показа комментариев и нажмите "Сохранить настройки" для активации изменений.

Back to top

(С) Виктор Вислобоков, 2008-2023