Предполагая, что функция foo()
не может быть встроенной, Postgres не знает, что она может вернуть, поэтому он должен предположить, что любое число одинаково распространено.
Предикат foo = 4
говорит Postgres ожидатьчто рядом с отсутствующей строкой будет соответствовать критериям.
Предикат foo != 0 AND foo != 2
, OTOH, сообщает Postgres ожидать, что почти все строки соответствуют требованиям.С foo > 2
это по-прежнему примерно половина всех строк.
Это обычно приводит к различным планам запросов, и первый кажется плохо работающим, в то время как другие, кажется, работают хорошо.
Детали скрыты отсутствующей информацией.Но в этом суть.
Если функция IMMUTABLE
, вы можете создать индекс выражения на foo(foo(id))
.Этот индекс, вероятно, сам по себе бесполезен, если предположить, что 3 возможных значения распределены равномерно.( Может быть сканирование только по индексу для многоколоночного индекса foo(foo(id), id)
поможет, если функция дорогая и объявлена как таковая.) Но это заставляет Postgres собирать дополнительную статистику, которая сообщит планировщику запросов, чего ожидатьиз функции.Связанный: