Pull to refresh

Comments 9

Перемещаем подзапрос в CTE: если запрос быстр сам по себе, мы можем просто сначала рассчитать быстрый результат, а затем предоставить его основному запросу

Это вообще так не работает. СТЕ это подзапрос, чисто синтаксически более удобно оформленный.

SQL декларативный язык. То, что господин Manish с помощью переписывания текста запроса в другом формате получил более быстрое выполнение, это означает либо проблемы оптимизатора запросов у PostgreSQL либо у него проблемы со статистикой либо индексами либо пониманием данных, которые он запрашивал.

из этой истории можно извлечь немало уроков:

А где урок №1: начинать с «EXPLAIN ANALYZE» и научиться понимать «непрозрачности планировщиков запросов»

Возможно, вы путаете Postgres с MS SQL. В последнем действительно CTE — это поздзапрос, записанный в другой форме, а в Postgres оно материализуется (вроде бы в какой-то из последних версий добавили возможность не материализовывать CTE с помощью опции).


Что касается довода "SQL декларативный язык. То, что господин Manish с помощью переписывания текста запроса в другом формате получил более быстрое выполнение, это означает либо проблемы оптимизатора запросов у PostgreSQL..." — это так не работает. Да, оптимизатор не всесилен, и если переписывание запроса помогает ускорить его в десятки раз — надо переписывать. Ну или ждать, когда вендор научит СУБД правильно оптимизировать такой вариант запроса.

Перечитал документацию. К сожалению у PostgreSQL нет таких опций, а решение materialize/inline принимает «божественный» планировщик. Зимой отгреб из-за этого проблему, потому-что после какого-то сбора статистики планировщик внезапно перестал делать condition pushdown из основного запроса в CTE.

Вот статья, из которой я узнал про это https://m.habr.com/en/post/440576/
Отложилось в памяти, что это какая-то новая возможность, но не запомнил, это уже в релизе или в планах.
По работе с постгресом уже несколько лет не взаимодействовал, да и до этого не скажу чтобы прям глубоко погружался, так что многих тонкостей не знаю.

Это вам большое спасибо за информацию. Если постгре так "оптимизирует" запросы, что при изменении порядка слов меняется порядок выполнения, то это конечно отличный пример за что берут деньги в МС и почему потом приходится клепать костыли, что бы "не материализовывать". Ну то есть вариант "проблема оптимизатора запросов" + товарищ не знает свой инструмент и "пробует" сте хотя его инструмент интерпретирует сте специфично.


"оптимизатор не всесилен, и если переписывание запроса помогает ускорить его в десятки раз — надо переписывать"
Конечно надо. Только не методом пальца в небо надо переписывать, а читая план выполнения, оценивая каждую операцию и ища проблему там. Потом да, можно использовать хинты или уловки или административные меры типа создания индекса, когда понятно в чем дело. А в статье идёт речь именно про тыкание пальцем как методику решения проблемы.

Затем, для небольшого подмножества данных я проверил правильность всех результатов вручную.

Можно же в CSV экспортировать, например, и использовать diff

Иногда удобно проверить корректность через INTERSECT/EXCEPT

Но «проверить правильность результатов вручную» не обязательно значит «просмотреть все строки» (я искренне надеюсь на это).
Вывод из статьи только один — надо учиться читать план запроса. Для того кто понимает что происходит — он вполне прозрачен, а для кого нет — нахождение ошибок путём метода тыка будет не очень продуктивен и долог. Лучше оптимизировать именно это место )

Заодно это улучшит базовые знания работы с БД (которыми частенько пренебрегают...)
Согласен, добавить бы подробный план запроса в статью.
Когда попытался воспроизвести приведённые кейсы, понял, что нет объёма данных в таблицах и непонятно, как распределены значения в массиве urls.
Sign up to leave a comment.

Articles