Строго говоря, термин «хранимые процедуры» указывает на процедуры SQL в Postgres, введенные в Postgres 11.
Есть также функции , выполняющие почти, но не совсем то же самое, и они были там с самого начала.
Функции с LANGUAGE sql
, в основном, представляют собой просто пакетные файлы с простыми командами SQL в оболочке функций (и, следовательно, атомарные, всегда выполняемые внутри одной транзакции), принимающие параметры. Все операторы в функции SQL планируются сразу , что несколько отличается от выполнения одного оператора за другим и может влиять на порядок, в котором принимаются блокировки.
Для чего-то большего, самый зрелый язык - это PL / pgSQL ( LANGUAGE plpgsql
). Он хорошо работает и улучшается с каждым выпуском за последнее десятилетие, но лучше всего служит связующим звеном для команд SQL. Он не предназначен для тяжелых вычислений (кроме команд SQL).
Функции PL / pgSQL выполняют запросы как подготовленные операторы . Повторное использование кэшированных планов запросов сокращает некоторые затраты на планирование и делает их немного быстрее, чем эквивалентные операторы SQL, что может быть заметным эффектом в зависимости от обстоятельств. У этого могут также быть побочные эффекты как в этом связанном вопросе:
Это несет в себе преимущества и недостатки подготовленных заявлений - как описано в руководстве . Для запросов к таблицам с нерегулярным распределением данных и изменяющимися параметрами динамический SQL с EXECUTE
может работать лучше, когда выгода от оптимизированного плана выполнения для данного параметра (параметров) превышает стоимость перепланирования.
Начиная с Postgres 9.2 общие планы выполнения все еще кэшируются для сеанса, но, цитируя руководство :
Это происходит немедленно для подготовленных операторов без параметров; в противном случае это происходит только после того, как пять или более исполнений произведут планы, чьи средние сметные расходы (включая накладные расходы на планирование) стоят дороже, чем сметная стоимость общего плана.
Мы получаем лучшее из обоих миров большую часть времени (за исключением некоторых дополнительных затрат) без использования (ab) EXECUTE
. Подробности в Что нового в PostgreSQL 9.2 из PostgreSQL Wiki .
Postgres 12 вводит дополнительную переменную сервераplan_cache_mode
для принудительного использования общих или пользовательских планов. Для особых случаев используйте с осторожностью.
Вы можете выиграть с помощью функций на стороне сервера, которые предотвращают дополнительные обращения к серверу базы данных из вашего приложения. Пусть сервер выполнит как можно больше за один раз и вернет только четко определенный результат.
Избегайте вложения сложных функций, особенно табличных функций ( RETURNING SETOF record
или TABLE (...)
). Функции - это черные ящики, которые представляют собой барьеры оптимизации для планировщика запросов. Они оптимизируются отдельно, а не в контексте внешнего запроса, что упрощает планирование, но может привести к неудачным планам. Кроме того, стоимость и размер результата функций не могут быть надежно предсказаны.
Исключение из этого правила являются простые функции SQL ( LANGUAGE sql
), которые могут быть «встраиваются» - если какие - то предварительные условия . Узнайте больше о том, как планировщик запросов работает в этой презентации Нила Конвея (продвинутый материал).
В PostgreSQL функция всегда автоматически запускается внутри одной транзакции . Все это удается или ничего. Если возникает исключение, все откатывается. Но есть обработка ошибок ...
Вот почему функции не совсем «хранимые процедуры» (хотя этот термин используется иногда, вводит в заблуждение). Некоторые команды, например VACUUM
, CREATE INDEX CONCURRENTLY
или CREATE DATABASE
не могут выполняться внутри блока транзакции, поэтому они не разрешены в функциях. (Пока нет ни в процедурах SQL, ни в Postgres 11. Это может быть добавлено позже.)
За эти годы я написал тысячи функций plpgsql.