Postgres все подзапросы в коалессе выполнены - PullRequest
0 голосов
/ 29 марта 2020

COALESCE в Postgres - это функция, которая возвращает первый параметр, отличный от NULL. Поэтому я использовал coalesce в подзапросах, таких как:

SELECT COALESCE (
 ( SELECT * FROM users WHERE... ORDER BY ...),
 ( SELECT * FROM users WHERE... ORDER BY ...),
 ( SELECT * FROM users WHERE... ORDER BY ...),
 ( SELECT * FROM users WHERE... ORDER BY ...)
);

Я изменяю где в любом запросе, и они содержат много параметров и CASE, а также различные предложения ORDER BY. Это потому, что я всегда хочу что-то вернуть, но с указанием приоритетов.

Что я заметил при выдаче EXPLAIN ANALYZE, так это то, что любой запрос выполняется, несмотря на то, что первый фактически возвращает НЕ пустое значение. Я ожидаю, что движок выполнит только первый запрос, а не следующие, если он вернет не ноль.

Таким образом, у меня может быть плохая производительность.

Так что я делаю что-то плохое попрактиковаться и лучше ли выполнять запросы отдельно по соображениям производительности?

РЕДАКТИРОВАТЬ:

Извините вас, где правильно, я не выбираю *, но я выбираю только один столбец. Я не опубликовал свой код, потому что мне не интересен мой запрос, но это общий вопрос c, чтобы понять, как работает двигатель. Поэтому я воспроизвожу очень простую скрипку здесь http://sqlfiddle.com/#! 17 / a8aa7 / 4

Возможно, я ошибаюсь, но я думаю, что она ведет себя так, как я говорил: она запускает все подзапросы, несмотря на первый из них уже возвращает ненулевое значение

РЕДАКТИРОВАТЬ 2: хорошо, я читаю только теперь он говорит, что никогда не выполнялся. Таким образом, два других запроса не выполняются. Меня смутило то, что они были включены в план запроса.

В любом случае, это все еще важно для моего вопроса. Лучше ли выполнять все запросы отдельно по соображениям производительности? Поскольку кажется, что даже если первый возвращает ненулевое значение, два других подзапроса могут снизить производительность

1 Ответ

1 голос
/ 29 марта 2020

Для отдельных SELECT запросов я предлагаю использовать UNION ALL / LIMIT 1. На основе ваша скрипка :

(select user_id from users order by age limit 1)  -- misleading example, see below
UNION ALL
(select user_id from users where user_id=1)
UNION ALL
(select user_id from users order by user_id DESC limit 1)
LIMIT 1;

дБ <> скрипка здесь

По трем причинам:

  1. Работает для любого SELECT списка: одиночные выражения (ваша скрипка), несколько или целая строка (ваш пример в вопросе).

  2. Вы можете отличить guish фактические NULL значения от "без строки". Поскольку user_id является PK в примере (и, следовательно, NOT NULL), проблема не может возникнуть в этом примере. Но с выражением, которое может быть NULL, COALESCE не может различить guish между обоими, "no row" приводится к NULL для цели запроса. См .:

  3. Быстрее.

Кроме того, ваш первый SELECT в примере превращает это в дикую погону goose. Возвращает строку, если есть хотя бы один. В этом случае все остальное - шум.

Связанный:

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