Оптимизированы ли множественные вызовы функции STABLE в CTE? - PullRequest
0 голосов
/ 23 декабря 2018

Согласно PostgreSQL: Документация: 38.7.Категории изменчивости функций :

Функция STABLE не может изменить базу данных и гарантированно возвращает одинаковые результаты при одинаковых аргументах для всех строк в одной инструкции.Эта категория позволяет оптимизатору оптимизировать несколько вызовов функции для одного вызова.

Как насчет использования CTE?Если я вызову функцию STABLE внутри CTE, а затем снова внутри основного запроса SELECT, оптимизатор оптимизирует оба вызова функции для одного вызова?

Как вы можете это определить?(Я не знаю, как использовать EXPLAIN.)

В приведенном ниже непрактичном примере я хочу убедиться, что функция get_user_by_id() вызывается только один раз.

CREATE TABLE users (
  id bigserial PRIMARY KEY,
  username varchar(64) NOT NULL
);

CREATE FUNCTION get_user_by_id(_id bigint) RETURNS users AS $$
  SELECT *
  FROM users
  WHERE id = _id
$$ LANGUAGE SQL STABLE;

INSERT INTO users (username) VALUES ('user1');

WITH error AS (
  SELECT -1 AS code
  WHERE (SELECT get_user_by_id(3) IS NULL)
)
SELECT code AS id, NULL AS username FROM error
UNION ALL
SELECT * FROM get_user_by_id(3) WHERE id IS NOT NULL;

1 Ответ

0 голосов
/ 23 декабря 2018

Я думаю, что ответ - нет, несколько вызовов функции STABLE не оптимизированы для CTE.Я не знаю, как это доказать, но согласно PostgreSQL: Документация: 11: 7.8.Запросы WITH (общие выражения таблиц) , CTE кажутся отдельными «вспомогательными операторами»И они, кажется, не очень хорошо интегрированы с родительским запросом.Например:

.,,Оптимизатор меньше способен выдвигать ограничения из родительского запроса в запрос WITH, чем обычный подзапрос.Запрос WITH, как правило, будет оцениваться как записанный, без подавления строк, которые родительский запрос может впоследствии отбросить.

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