как запретить представлениям postgres вызывать избыточные функции - PullRequest
0 голосов
/ 17 мая 2018

У меня есть такое представление

create view v1 as select a,b,c,foo1(e,f) as f1, foo2(g,h) as f2 from t1;

, когда я делаю

select a from v1;

foo1 и foo2 вызывают.Это удивило меня.(Других двигателей конечно нет).Foo1 и foo2 относительно дороги, поэтому я хочу, чтобы они оценивались, только если пользователь явно их запрашивает.Есть ли способ, которым я могу этого достичь?

1 Ответ

0 голосов
/ 17 мая 2018

Для такого поведения есть веская причина.

Каждая функция в Postgres имеет категорию волатильности : VOLATILE, STABLE или IMMUTABLE.Они служат двум целям:

  • Они сообщают оптимизатору запросов, можно ли пропустить вызов функции, повторно используя выходные данные.Например, он знает, что round() всегда будет возвращать один и тот же результат для данного аргумента, в то время как он не может сделать это предположение для чего-то вроде random().
  • Они сообщают оптимизатору, безопасен ли он , чтобы пропустить вызов функции.Если функция может иметь побочные эффекты (например, вставка записи), то вызовы нельзя оптимизировать без влияния на результат, поэтому для обеспечения предсказуемого поведения такая функция всегда будет оцениваться.

Категория волатильности не может быть автоматически выведена, поэтому Postgres по умолчанию использует самый безопасный вариант: функции имеют значение VOLATILE, если не указано иное, и поэтому планировщик запросов предполагает, что они могут иметь побочные эффекты.И даже если такая функция скрыта в представлении, а ее результат игнорируется вашим запросом, она все равно будет выполнена.

Если вы объявите свои функции как STABLE, они будут выполняться только тогда, когдарезультат действительно необходим.

(Вы можете сделать это независимо от того, действительно ли они STABLE, но если они имеют побочные эффекты, это может быть не в вашемнаилучшие интересы ...)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...