Как я могу получить текущее значение параметра локальной конфигурации postgresql?

Я практикуюсь с оптимизацией запросов (Postgres 13). В частности, настройка параметра work_mem.

Вот схема БД: https://postgrespro.com/docs/postgrespro/12/apks02.

У меня есть функция sql get_passengers_and_flights:

CREATE FUNCTION get_passengers_and_flights(d timestamptz)
RETURNS TABLE(passenger_name text, flight_no text)
AS $$
  SELECT t.passenger_name, f.flight_no
  FROM tickets t
    JOIN ticket_flights tf ON tf.ticket_no = t.ticket_no
    JOIN flights f ON f.flight_id = tf.flight_id
  WHERE f.scheduled_departure >= date_trunc('month', d)
    AND f.scheduled_departure  < date_trunc('month', d) + interval '1 month'
  ORDER BY f.scheduled_departure, t.passenger_name;
$$ LANGUAGE sql;

И простой запрос:

SELECT * FROM get_passengers_and_flights('2017-06-01') LIMIT 3;

По умолчанию workmem = '4MB', поэтому сортировка занимает некоторое время. Один из способов улучшить работу — увеличить work_mem с «4 МБ» до «32 МБ» или более. В последних версиях postgresql мы можем сделать это локально (для функции, таблицы и т. д.):

ALTER FUNCTION get_passengers_and_flights SET work_mem = '32MB';

Итак, была выбрана быстрая сортировка, и время выполнения сократилось.

Но вопрос в том, как я могу увидеть локальное значение work_mem для функции get_passengers_and_flights?

Очевидный способ получить значение work_mem:

SELECT current_setting('work_mem');

Вывод представляет собой глобальное значение «4 МБ», так как я могу получить локальное «32 МБ»? Я пробежался по описанию системных каталогов и ничего не нашел.

Я не уверен, как сделать именно то, что вы хотите, но... Чтобы заставить его, а не устанавливать и проверять его для каждого соединения, отредактируйте значение в /usr/local/var/postgres/postgresql.conf и перезапустите постгрес сервер. Просто будьте осторожны, так как это предназначено для предотвращения голодающих процессов. Я считаю, что общая оперативная память = work_mem * одновременные соединения. work_mem назначается для каждого соединения. Я точно не знаю, как проверить голодающие процессы, но есть чему поучиться.

Entree 29.04.2023 23:18

Вопрос такой: увидеть локальное значение где? Это просто видно внутри тела функции. Или действительно хотите увидеть свойства функции? (По сути, оператор CREATE FUNCTION.) Кроме того, в моих руках на Postgres 15 этот запрос использует Incremental Sort с таким маленьким LIMIT. Вы можете начать с неправильного дерева, но недостаточно информации, чтобы задать правильный вопрос о производительности. См.: stackoverflow.com/tags/postgresql/info

Erwin Brandstetter 30.04.2023 01:04

Я понимаю. У меня Postgres 13. Сначала он получает всю таблицу как результат функции, а затем подбирает ее. Так что у меня нет инкрементной сортировки в моем случае, потому что Postgres 13 просто не может заглянуть в результат функции до самого конца. Вероятно, это было исправлено в Postgres 15...

Alex 30.04.2023 08:28

Честно говоря, это не вопрос производительности. Я просто дал контекст проблемы. Это больше о настройке Postgres. В любом случае, спасибо за ваше мнение, в следующий раз постараюсь быть более точным.

Alex 30.04.2023 08:40

Прежде чем что-либо менять в конфигурации, я бы начал с плана запроса, используя EXPLAIN(ANALYZE, VERBOSE, BUFFERS). При правильном индексировании это должно быть молниеносно, даже с небольшой настройкой памяти для work_mem.

Frank Heikens 30.04.2023 10:21

Кстати, самая большая проблема — это LIMIT 3 вне функции.

Frank Heikens 30.04.2023 11:21

Вы не получите план выполнения запроса внутри функции, используя объяснение. Auto_explain — это способ. Что касается оптимизации, то я просто играюсь с локальными параметрами, в том-то и дело) Я не утверждаю, что это лучший способ оптимизировать запрос.

Alex 30.04.2023 17:51
ReactJs | Supabase | Добавление данных в базу данных
ReactJs | Supabase | Добавление данных в базу данных
Это и есть ваш редактор таблиц в supabase.👇
Понимание Python и переход к SQL
Понимание Python и переход к SQL
Перед нами лабораторная работа по BloodOath:
0
7
54
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Следующий запрос должен дать желаемые результаты:

SELECT
  REGEXP_SUBSTR(c.setting, '[^=]+$') AS work_mem
FROM
  pg_proc
  CROSS JOIN unnest(pg_proc.proconfig) c(setting)
WHERE
  oid = 'public.get_passengers_and_flights(timestamptz)'::regprocedure
  AND c.setting LIKE 'work_mem=%';

NULL возвращается, если work_mem не был локально сконфигурирован для функции.

Я пересмотрел свой ответ, чтобы обратиться к перегруженным функциям, используя regprocedure, чтобы гарантировать, что возвращается только настройка предполагаемой функции. Спасибо Эрвину Брандштеттеру за упоминание об этом.

JohnH 30.04.2023 09:13

Если все, что вам нужно, это просмотреть свойства созданной функции, используйте специальную функцию системной информации pg_get_functiondef():

SELECT pg_get_functiondef('public.get_passengers_and_flights(timestamptz)'::regprocedure);

Это надежно получает OID функции — при условии, что она создана в схеме public:

'public.get_passengers_and_flights(timestamptz)'::regprocedure

Видеть:

Другие вопросы по теме