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

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

Доброго времени суток. Подскажите а у вас в приложении действительно такие сложные сценарии/запросы используются? В первый раз вижу такие сложные оптимизации запросов (если в целом брать ваши статьи).
Да, это реальные кейсы. Иногда разница в нагрузке между наивной и оптимизированной версией бывает кратной, а «железо» все-таки не резиновое.
Спасибо. Действительно, очень интересно всегда Вас читать.
Пишите еще))
это все довольно простые запросы. Сложные — это запросы с полусотней джоинов, и подзапросами в 3-4 уровня. Причем на многомилионных таблицах.
Что-то типа такого? :)

Многие со мной не согласятся, но я считаю, что «полусотня джойнов» — это все-таки антипаттерн, если нет задачи «написать, чтобы просто хоть один раз отработал».

Ну и проблемы в больших и сложных запросах обычно появляются как следствие проблем в их маленьких кусочках — вроде таких вариантов с DISTINCT.
Ну для витрин данных — просто разбивать 50 джоинов на 5 подвитрин по 10 — смысла не много, если они не переиспользуются. А полста джоинов — это еще мало если просто справочников на факте висит пару дюжин (а бывает для нормального отчета надо и 100 справочников). Конечно большинство из них прямые и простые как валенок хэш джоины, без сюрпризов, но обязательно попадется и справочник без pk, и scd2 и фактов не один а штук 10. И вот уже джоины с подзапросами и дедубликакцией и оконных функций полно т.д. в итоге и получается 5 страниц кода в одном запросе.
Хотя работает при этом все один проход и быстро.

А разве планировщик/оптимизатор не соптимизирует такие запросы, даже если написать откровенную чушь?
Если подать откровенную чушь на вход, результат будет соответствующий. И странно ожидать иного.
А как же без него?
Так:

SELECT
  *
FROM
  X
WHERE
  EXISTS(
    SELECT
    FROM
select без полей — это как-то совсем некрасиво. А парсер от какой версии такое понимает?
Испокон веков.
У меня вот 9.3, пустой SELECT вызывает ошибку синтаксиса
Экая древность. Он разве ещё поддерживается?
Я так понимаю, у вас «испокон веков» понятие плавающее?
Если что, то вполне себе используется, и до кучи заявленное поведение начало работать только с версии 9.4
Для меня шесть лет — вполне себе срок, чтобы так говорить. Скоро уже 13-я версия Постгреса выйдет.
Если что, то вполне себе используется…
Я про поддержку говорю, использование — на вашей совести.
Можете объяснить, почему во втором примере («Зачем платить больше»: DISTINCT [ON] + LIMIT 1) запросы эквивалентны в общем случае?

Если рассматривать join, а не left join, то возможна же ситуация, когда этот
SELECT
  *
FROM
  (
    SELECT
      *
    FROM
      X
    -- сюда можно подсунуть подходящих условий
    LIMIT 1 -- +1 Limit
  ) X
JOIN
  Y
    ON Y.fk = X.pk

джоин даст в результате 0 записей. Хотя если убрать LIMIT 1, то записи найдутся.
В общем случае они НЕ эквивалентны, но мы рассматриваем именно ситуацию, когда разницы нет — например, если по прикладным причинам всегда имеет место хотя бы одна связанная запись.

Или, если поменять X и Y местами, пример станет нагляднее, когда Y.fk действительно foreign key.
Зарегистрируйтесь на Хабре , чтобы оставить комментарий