powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / PostgreSQL [игнор отключен] [закрыт для гостей] / Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
6 сообщений из 6, страница 1 из 1
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39612722
sKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Доброго времени суток, коллеги.

Необходима помощь в следующей ситуации: небольшой запрос в хранимой процедуре выполняется значительно медленнее, чем показывает его explain analyze.

explain analyze я вставил непосредственно в хранимую процедуру перед выполнением запроса. Вот результат pg_stat после отработки процедуры:

Это результат непосредственно запроса в pg_stat:
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
create temporary table TMP_J_RES on commit drop as select ps__r.CONTRACT_ID as __ID
 from PRISOS ps__r
inner join CONTRACT c__r
  on ps__r.CONTRACT_ID = c__r.CONTRACT_ID
inner join SUBJECT s__r
  on c__r.SUBJECT_ID = s__r.SUBJECT_ID
 where 
  lower(s__r.FULL_NAME) like '%иван%'
 order by ps__r.PRISOS_SS_PROP desc
 offset 0 limit 50

total_time      12790.189798



Это его explain, вызванный прямо в процедуре (в pg_stat):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
explain analyze select ps__r.CONTRACT_ID as __ID
 from PRISOS ps__r
inner join CONTRACT c__r
  on ps__r.CONTRACT_ID = c__r.CONTRACT_ID
inner join SUBJECT s__r
  on c__r.SUBJECT_ID = s__r.SUBJECT_ID
 where 
  lower(s__r.FULL_NAME) like '%иван%'
 order by ps__r.PRISOS_SS_PROP desc
 offset 0 limit 50

total_time      4785.438513



Сам план и анализ запроса (из процедуры):
Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
Limit  (cost=165361.82..165367.66 rows=50 width=13) (actual time=4602.238..4602.279 rows=50 loops=1)
  ->  Gather Merge  (cost=165361.82..165379.32 rows=150 width=13) (actual time=4602.236..4602.271 rows=50 loops=1)
        Workers Planned: 2
        Workers Launched: 2
        ->  Sort  (cost=164361.80..164361.99 rows=75 width=13) (actual time=4597.670..4597.691 rows=148 loops=3)
              Sort Key: ps__r.prisos_ss_prop DESC
              Sort Method: quicksort  Memory: 423kB
              ->  Nested Loop  (cost=0.86..164359.46 rows=75 width=13) (actual time=846.793..4589.192 rows=5159 loops=3)
                    ->  Nested Loop  (cost=0.43..164249.30 rows=222 width=8) (actual time=1.650..4485.833 rows=15228 loops=3)
                          ->  Parallel Seq Scan on subject s__r  (cost=0.00..162238.90 rows=240 width=8) (actual time=1.594..4291.891 rows=16446 loops=3)
                                Filter: (lower((full_name)::text) ~~ '%иван%'::text)
                                Rows Removed by Filter: 1925070
                          ->  Index Scan using fk_subject_contract_fk on contract c__r  (cost=0.43..8.37 rows=1 width=16) (actual time=0.010..0.010 rows=1 loops=49338)
                                Index Cond: ((subject_id)::bigint = (s__r.subject_id)::bigint)
                    ->  Index Scan using fk_contract_prisos_fk on prisos ps__r  (cost=0.43..0.49 rows=1 width=13) (actual time=0.006..0.006 rows=0 loops=45683)
                          Index Cond: ((contract_id)::bigint = (c__r.contract_id)::bigint)
Planning time: 1.067 ms
Execution time: 4629.548 ms




Если запрос выполнять из консоли, то время выполнения около 4.5 сек, что соответствует результату explain analyze

work_mem - 1GB
vacuum analyze выполнен прямо перед тестом.

Создание временной таблицы не может быть камнем преткновения, т.к. аналогичные таблицы в этой же процедуре создаются примерно за 3 мс.
Результат запроса - 50 строк, содержащих int8.
...
Рейтинг: 0 / 0
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39612726
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sKot,

CREATE TABLE AS отключает параллельное выполнение запроса на нескольких ядрах.
Вот и получаете замедление в 2 с копейками раза относительно просто запроса

PS: сделайте триграмный индекс на lower(s__r.FULL_NAME - и будет вам счастье что с хранимкой что без
https://www.postgresql.org/docs/10/static/pgtrgm.html
...
Рейтинг: 0 / 0
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39612767
sKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Максим, спасибо!

Правильно ли я понимаю, что "open cursor for execute" также отключает параллельное выполнение? Если я из процедуры возвращаю refcursor, то время выполнения запроса такое же как и для create table as.
Есть ли способ возвращать их процедуры некое результирующее множество с произвольным набором столбцов?
Пробовал "RETURN QUERY EXECUTE", но он требует определение типа для возвращаемых записей, а результирующий запрос содержит недетерменированное количество столбцов (зависит от параметров, передаваемых в ХП).

Триграммы попробую, по результатам отпишусь.
...
Рейтинг: 0 / 0
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39612851
sKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Максим, я ещё не понял в чём тут подвох, но ускорение на триграммных индексах более чем в 7 раз!!!

Код: sql
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
select
<Много полей отбора>
from PRISOS ps
inner join (
select ps__r.CONTRACT_ID as __ID
 from PRISOS ps__r
inner join CONTRACT c__r
  on ps__r.CONTRACT_ID = c__r.CONTRACT_ID
inner join SUBJECT s__r
  on c__r.SUBJECT_ID = s__r.SUBJECT_ID
 where 
  lower(s__r.FULL_NAME) like $1
 order by ps__r.PRISOS_SS_PROP desc
 offset $2 limit $3) __t1 on __t1.__ID = ps.CONTRACT_ID
<Много left join'ов>

total_time   1767.701945



СПАСИБО ОГРОМНОЕ!
...
Рейтинг: 0 / 0
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39612933
Фотография Maxim Boguk
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sKotМаксим, спасибо!

Правильно ли я понимаю, что "open cursor for execute" также отключает параллельное выполнение? Если я из процедуры возвращаю refcursor, то время выполнения запроса такое же как и для create table as.


Да отключает. Почти все кроме просто написанного select сейчас отключает параллельное выполнение запросов по ряду причин архитектурных.

--
Maxim Boguk
dataegret.ru
...
Рейтинг: 0 / 0
Запрос в хранимой процедуре выполняется медленне, чем показывает explain analyze
    #39613076
sKot
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Максим, спасибо.

Помогли GIST индексы, а не танцы с бубном около refcursor'ов и временных таблиц.

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


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