Функции Postgres объявлены с классификацией волатильности VOLATILE
, STABLE
илиIMMUTABLE
. Известно, что проект очень строг с этими метками для встроенных функций. И не без причины. Показательный пример: индексы выражений допускают только IMMUTABLE
функции, и они должны быть действительно неизменными, чтобы избежать неверных результатов.
Пользовательские функции все еще могут быть объявлены по усмотрению владельца. Руководство советует:
Для достижения наилучших результатов оптимизации вы должны пометить свои функции категорией самой строгой волатильности, которая действительна для них.
... и добавляет обширный список вещей, которые могут пойти не так с неправильной меткой волатильности.
Тем не менее, есть случаи, когда имитация неизменности имеет смысл. Главным образом, когда вы знаете, что функция фактически неизменна в вашей области видимости. Пример:
За исключением всех возможных последствий для целостности данных , как это влияет на производительность? Можно предположить, что объявление функции IMMUTABLE
может быть полезным только для производительности . Это так?
Может ли объявление волатильности функций IMMUTABLE
повредить производительности?
Давайте предположим, что нынешний Postgres 10 сузит его, но все последние версии представляют интерес.
источник
FORCE
любом случае. 100% опытных администраторов баз данных PostgreSQL лгут, чтобы обойти этот пользовательский интерфейс с помощью функций-оболочек. По крайней мереFORCE
, нам не понадобятся обертки, и нам не придется лежать на объявленной волатильности.FORCE
что предполагается, что индексы выражений принимают неизменные функции (помечая их как потенциальную точку отказа). Да, это кажется более элегантным решением, чем обертки с неизменяемыми функциями.Ответы:
Да, это может повредить производительности.
Простые функции SQL могут быть «встроены» в вызывающий запрос. Цитирую Postgres Wiki :
Жирный акцент мой.
Для обеспечения правильности существует ряд предварительных условий. Один из них :
Это означает, что функции SQL, использующие любые неизменяемые функции, но все еще объявленные
IMMTUTABLE
, исключаются из этой оптимизации. Вызванные этими связанными ответами на SO, я провел обширные тесты:В основном, сравнивая эти два варианта простой функции SQL (сопоставление дат и
integer
игнорирование года, который не имеет значения для этой цели):Функция Postgres
to_char()
есть толькоSTABLE
, нетIMMUTABLE
(все ее перегруженные экземпляры - по причинам, выходящим за рамки этого ответа ). Таким образом, второй - фальшивкаIMMUTABLE
и оказывается в 5 раз медленнее в простом тесте:дБ <> скрипка здесь
Этот конкретный пример можно заменить на эквивалентный:
Казалось бы , дороже с двумя вызовами функций и большим количеством вычислений. Но
IMMUTABLE
метка верна (плюс, используемая функция быстрее и принуждениеtext
к томуinteger
же дороже).В 2 раза быстрее, чем вышеупомянутый вариант (в 10 раз быстрее, чем медленнее). Суть в том, что: используйте
IMMUTABLE
функции там , где это возможно , тогда вам не нужно «обманывать» для начала.источник
STABLE
тоже встраивание. Я думал, что оптимизатор будетIMMUTABLE
работать только онлайн .VOLATILE
точно также.