У меня есть запрос в функции plpgsql (см. Ниже, упрощен для ясности), который замедляет работу после 4 или 5 запусков в 5 раз (время работы от ~ 700 мс до ~ 3,5 секунд). Если я удалю и заново создаю функцию, она начнется быстрее: примерно 5 раз, а затем медленно. Итак, похоже, что что-то происходит с оптимизатором запросов, но я не могу получить план запроса, так как он находится в функции. Если я запустил запрос вне функции с одинаковыми входами, он работает нормально, независимо от того, сколько раз он запускается. Если я прокомментирую 3 левых соединения, удерживая их внутри функции, снова он работает нормально. Итак, я пришел к выводу, что это связано с левыми объединениями, но об этом.Запрос postgresql в функции plpgsql замедляется после нескольких запусков
Подробнее о запросе: у него есть статья with as
, после возврата data
с примерно 5000 строк и 40 строк; затем он подключается к сети 3 раза, чтобы переместить некоторую информацию из строк в столбцы (это уменьшает количество строк до 1000).
create or replace function public.a_function(
-- 5 input parameters here
)
returns table (a text, b integer, ...) -- about 40 output columns
as $$
declare
...
begin
... --logic to prepare two arrays used in query below: array_a and array_b
return query
with data as ( -- this part of the query returns ~5000 rows and 40 columns
select d.*
from public.dashboard_data_view d -- ~10 million rows in this view
where d.organization_id = any (array_a) -- array_a: 4 values in int[]
and d.element_id = any (array_b) -- array_b: ~10,000 values in int[]
)
select c.*, c.value, d.value, r.value, s.value
from (select * from data where data.population = 'C') c -- this reduces rows down to ~1000
left join (select * from data where data.population = 'D') d on d.common_id = c.common_id
left join (select * from data where data.population = 'R') r on r.common_id = c.common_id
left join (select * from data where data.population = 'S') s on s.common_id = c.common_id
;
end
$$ language plpgsql stable;
;
информация Платформа: Postgres 9.3 на Ubuntu LTS 14 перспективе на Вагрант VM с 4 Гб оперативной памяти и 2 процессоров. shared_buffers
= 1000 МБ (1/4-е от общего числа) и work_mem
= 128 МБ (разработка машины, не так много происходит параллельно).
Итак, что может вызвать замедление или что я могу сделать для дальнейшего расследования?
Обновление: я вставил значение array_b в запрос как буквальные (вместо того, чтобы использовать переменный), она работала хорошо. В представлении около 16K element_id, и фильтрация около ~ 10K из них, кажется, оптимизатор решает использовать последовательное сканирование вместо сканирования индекса через 5 раз. Это мое подозрение, но я не уверен.