Для такого поведения есть веская причина.
Каждая функция в Postgres имеет категорию волатильности : VOLATILE
, STABLE
или IMMUTABLE
.Они служат двум целям:
- Они сообщают оптимизатору запросов, можно ли пропустить вызов функции, повторно используя выходные данные.Например, он знает, что
round()
всегда будет возвращать один и тот же результат для данного аргумента, в то время как он не может сделать это предположение для чего-то вроде random()
. - Они сообщают оптимизатору, безопасен ли он , чтобы пропустить вызов функции.Если функция может иметь побочные эффекты (например, вставка записи), то вызовы нельзя оптимизировать без влияния на результат, поэтому для обеспечения предсказуемого поведения такая функция всегда будет оцениваться.
Категория волатильности не может быть автоматически выведена, поэтому Postgres по умолчанию использует самый безопасный вариант: функции имеют значение VOLATILE
, если не указано иное, и поэтому планировщик запросов предполагает, что они могут иметь побочные эффекты.И даже если такая функция скрыта в представлении, а ее результат игнорируется вашим запросом, она все равно будет выполнена.
Если вы объявите свои функции как STABLE
, они будут выполняться только тогда, когдарезультат действительно необходим.
(Вы можете сделать это независимо от того, действительно ли они STABLE
, но если они имеют побочные эффекты, это может быть не в вашемнаилучшие интересы ...)