Как стать автором
Обновить

Комментарии 7

UNION ALL vs UNION [DISTINCT]

Думаю, нужно добавить информацию о том, что объединение выполняется последовательно - то есть если в запросе имеется несколько UNION, каждый очередной UNION будет объединять текущую выборку с выборкой, которую получил предыдущий UNION:

Это позволяет ускорить получение уникализованной сборки нескольких наборов записей, применив UNION DISTINCT только на самом последнем объединении - в таком случае сервер должен будет выполнить всего одну сортировку, пусть и более объёмного набора записей, а не несколько сортировок после каждого UNION.

Осторожнее с NULL'ами!

https://dbfiddle.uk/WVjeYK5o

Как-то результат не совпадает с опубликованным в статье. Что я не так делаю?

При этом UNIONINTERSECT и EXCEPT могут произвольным образом комбинироваться в одном запросе.

С учётом самого первого моего замечания - при этом нужно весьма внимательно относиться к порядку применения операций и модификаторов ALL / DISTINCT.

или просто UNION, но его внутри рекурсии стоит использовать с осторожностью ... На каждом следующем шаге рекурсии такой запрос получает "на вход" (под именем "своей" CTE) результат генерации записей предыдущего сегмента, пока этот результат непустой, или затравочную выборку - для первого шага

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

если в запросе имеется несколько UNION, каждый очередной UNION будет объединять текущую выборку с выборкой, которую получил предыдущий UNION

Формально, X UNION Y UNION Z транслируется как (X UNION Y) UNION Z - так что не вижу смысла тут усложнять описание, про приоритет и так написано.

Это позволяет ускорить получение уникализованной сборки нескольких наборов записей, применив UNION DISTINCT только на самом последнем объединении

Хорошее замечание, но это уже к теме следующей лекции.

Как-то результат не совпадает с опубликованным в статье. Что я не так делаю?

Переписал абзац, поправил слайд. Спасибо!

просто UNION, но его внутри рекурсии стоит использовать с осторожностью ... Непонятно, из-за чего тут требует осторожничать.. или есть ещё какие-то резоны?

Приходилось встречать код примерно с таким смыслом:

WITH RECURSIVE T(i) AS (
  VALUES(1)
UNION
  SELECT
    j
  FROM
    T
  , generate_series(1, T.i + 1) j
  WHERE
    i < 10
)
TABLE T;

Он, конечно, корректно работает, но ни разу не эффективно. Но "простой" UNION маскирует эту проблему.

Пользуясь случаем - спрошу, может передадите вопрос коллегам: почему в вашем приложении SabyMy, которое вообще-то содержит достаточно конфиденциальную информацию, вообще нет никакой аутентификации при запуске?

Спасибо за статьи, внимательно изучаю, помогают разобраться с разными нюансами!

Вот в Совместное вычисление по разным "окнам" подзависла:

В этом примере мы разбили всю выборку по целочисленному остатку от деления i на 5

Все-таки не остаток от деления, а целочисленное деление?

Результату деления, конечно. Спасибо, поправил.

... и в комментариях скрипта ANY/ALL вместо "меньше" нужно "больше"
a < ANY(TABLE Y) -- хоть кто-то меньше этого значения a?

Конечно, спасибо, поправил.

Зарегистрируйтесь на Хабре, чтобы оставить комментарий